diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2019-08-09 12:15:49 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-08-10 14:41:26 -0400 |
commit | 672cbab268342d7a8829698e838e369e0a0b3a19 (patch) | |
tree | defa8c0075ac9ea2b4e0233f7244091de6820fd9 | |
parent | 0424de2d7138763417642650a4fb09f55aa9d8d1 (diff) | |
download | haskell-672cbab268342d7a8829698e838e369e0a0b3a19.tar.gz |
Reformat comments in StgSyn
This does not make any changes in the contents -- formatting only.
Previously the comments were too noisy and I've always found it very
hard to read. Hopefully it's easier to read now.
-rw-r--r-- | compiler/stgSyn/StgSyn.hs | 299 |
1 files changed, 141 insertions, 158 deletions
diff --git a/compiler/stgSyn/StgSyn.hs b/compiler/stgSyn/StgSyn.hs index dc0960ebb7..2448fbcfc8 100644 --- a/compiler/stgSyn/StgSyn.hs +++ b/compiler/stgSyn/StgSyn.hs @@ -1,7 +1,8 @@ {- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -\section[StgSyn]{Shared term graph (STG) syntax for spineless-tagless code generation} +Shared term graph (STG) syntax for spineless-tagless code generation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This data type represents programs just before code generation (conversion to @Cmm@): basically, what we have is a stylised form of @CoreSyntax@, the style @@ -89,14 +90,13 @@ import Data.List.NonEmpty ( NonEmpty, toList ) {- ************************************************************************ * * -\subsection{@GenStgBinding@} +GenStgBinding * * ************************************************************************ -As usual, expressions are interesting; other things are boring. Here -are the boring things [except note the @GenStgRhs@], parameterised -with respect to binder and occurrence information (just as in -@CoreSyn@): +As usual, expressions are interesting; other things are boring. Here are the +boring things (except note the @GenStgRhs@), parameterised with respect to +binder and occurrence information (just as in @CoreSyn@): -} -- | A top-level binding. @@ -112,7 +112,7 @@ data GenStgBinding pass {- ************************************************************************ * * -\subsection{@StgArg@} +StgArg * * ************************************************************************ -} @@ -121,8 +121,8 @@ data StgArg = StgVarArg Id | StgLitArg Literal --- | Does this constructor application refer to --- anything in a different *Windows* DLL? +-- | Does this constructor application refer to anything in a different +-- *Windows* DLL? -- If so, we can't allocate it statically isDllConApp :: DynFlags -> Module -> DataCon -> [StgArg] -> Bool isDllConApp dflags this_mod con args @@ -137,17 +137,22 @@ isDllConApp dflags this_mod con args && isDllName dflags this_mod (idName v) is_dll_arg _ = False --- True of machine addresses; these are the things that don't --- work across DLLs. The key point here is that VoidRep comes --- out False, so that a top level nullary GADT constructor is --- False for isDllConApp +-- True of machine addresses; these are the things that don't work across DLLs. +-- The key point here is that VoidRep comes out False, so that a top level +-- nullary GADT constructor is False for isDllConApp +-- -- data T a where -- T1 :: T Int +-- -- gives +-- -- T1 :: forall a. (a~Int) -> T a +-- -- and hence the top-level binding +-- -- $WT1 :: T Int -- $WT1 = T1 Int (Coercion (Refl Int)) +-- -- The coercion argument here gets VoidRep isAddrRep :: PrimRep -> Bool isAddrRep AddrRep = True @@ -191,26 +196,25 @@ stgCaseBndrInScope alt_ty unarised = {- ************************************************************************ * * -\subsection{STG expressions} +STG expressions * * ************************************************************************ -The @GenStgExpr@ data type is parameterised on binder and occurrence -info, as before. +The @GenStgExpr@ data type is parameterised on binder and occurrence info, as +before. ************************************************************************ * * -\subsubsection{@GenStgExpr@ application} +GenStgExpr * * ************************************************************************ -An application is of a function to a list of atoms [not expressions]. -Operationally, we want to push the arguments on the stack and call the -function. (If the arguments were expressions, we would have to build -their closures first.) +An application is of a function to a list of atoms (not expressions). +Operationally, we want to push the arguments on the stack and call the function. +(If the arguments were expressions, we would have to build their closures +first.) -There is no constructor for a lone variable; it would appear as -@StgApp var []@. +There is no constructor for a lone variable; it would appear as @StgApp var []@. -} data GenStgExpr pass @@ -221,18 +225,18 @@ data GenStgExpr pass {- ************************************************************************ * * -\subsubsection{@StgConApp@ and @StgPrimApp@---saturated applications} +StgConApp and StgPrimApp --- saturated applications * * ************************************************************************ -There are specialised forms of application, for constructors, -primitives, and literals. +There are specialised forms of application, for constructors, primitives, and +literals. -} | StgLit Literal -- StgConApp is vital for returning unboxed tuples or sums - -- which can't be let-bound first + -- which can't be let-bound | StgConApp DataCon [StgArg] -- Saturated [Type] -- See Note [Types in StgConApp] in UnariseStg @@ -246,13 +250,13 @@ primitives, and literals. {- ************************************************************************ * * -\subsubsection{@StgLam@} +StgLam * * ************************************************************************ -StgLam is used *only* during CoreToStg's work. Before CoreToStg has -finished it encodes (\x -> e) as (let f = \x -> e in f) -TODO: Encode this via an extension to GenStgExpr à la TTG. +StgLam is used *only* during CoreToStg's work. Before CoreToStg has finished it +encodes (\x -> e) as (let f = \x -> e in f) TODO: Encode this via an extension +to GenStgExpr à la TTG. -} | StgLam @@ -262,7 +266,7 @@ TODO: Encode this via an extension to GenStgExpr à la TTG. {- ************************************************************************ * * -\subsubsection{@GenStgExpr@: case-expressions} +GenStgExpr: case-expressions * * ************************************************************************ @@ -280,93 +284,74 @@ This has the same boxed/unboxed business as Core case expressions. {- ************************************************************************ * * -\subsubsection{@GenStgExpr@: @let(rec)@-expressions} +GenStgExpr: let(rec)-expressions * * ************************************************************************ -The various forms of let(rec)-expression encode most of the -interesting things we want to do. -\begin{enumerate} -\item -\begin{verbatim} -let-closure x = [free-vars] [args] expr -in e -\end{verbatim} -is equivalent to -\begin{verbatim} -let x = (\free-vars -> \args -> expr) free-vars -\end{verbatim} -\tr{args} may be empty (and is for most closures). It isn't under -circumstances like this: -\begin{verbatim} -let x = (\y -> y+z) -\end{verbatim} -This gets mangled to -\begin{verbatim} -let-closure x = [z] [y] (y+z) -\end{verbatim} -The idea is that we compile code for @(y+z)@ in an environment in which -@z@ is bound to an offset from \tr{Node}, and @y@ is bound to an -offset from the stack pointer. - -(A let-closure is an @StgLet@ with a @StgRhsClosure@ RHS.) - -\item -\begin{verbatim} -let-constructor x = Constructor [args] -in e -\end{verbatim} - -(A let-constructor is an @StgLet@ with a @StgRhsCon@ RHS.) - -\item -Letrec-expressions are essentially the same deal as -let-closure/let-constructor, so we use a common structure and -distinguish between them with an @is_recursive@ boolean flag. - -\item -\begin{verbatim} -let-unboxed u = an arbitrary arithmetic expression in unboxed values -in e -\end{verbatim} -All the stuff on the RHS must be fully evaluated. -No function calls either! - -(We've backed away from this toward case-expressions with -suitably-magical alts ...) - -\item -~[Advanced stuff here! Not to start with, but makes pattern matching -generate more efficient code.] - -\begin{verbatim} -let-escapes-not fail = expr -in e' -\end{verbatim} -Here the idea is that @e'@ guarantees not to put @fail@ in a data structure, -or pass it to another function. All @e'@ will ever do is tail-call @fail@. -Rather than build a closure for @fail@, all we need do is to record the stack -level at the moment of the @let-escapes-not@; then entering @fail@ is just -a matter of adjusting the stack pointer back down to that point and entering -the code for it. - -Another example: -\begin{verbatim} -f x y = let z = huge-expression in - if y==1 then z else - if y==2 then z else - 1 -\end{verbatim} - -(A let-escapes-not is an @StgLetNoEscape@.) - -\item -We may eventually want: -\begin{verbatim} -let-literal x = Literal -in e -\end{verbatim} -\end{enumerate} +The various forms of let(rec)-expression encode most of the interesting things +we want to do. + +- let-closure x = [free-vars] [args] expr in e + + is equivalent to + + let x = (\free-vars -> \args -> expr) free-vars + + @args@ may be empty (and is for most closures). It isn't under circumstances + like this: + + let x = (\y -> y+z) + + This gets mangled to + + let-closure x = [z] [y] (y+z) + + The idea is that we compile code for @(y+z)@ in an environment in which @z@ is + bound to an offset from Node, and `y` is bound to an offset from the stack + pointer. + + (A let-closure is an @StgLet@ with a @StgRhsClosure@ RHS.) + +- let-constructor x = Constructor [args] in e + + (A let-constructor is an @StgLet@ with a @StgRhsCon@ RHS.) + +- Letrec-expressions are essentially the same deal as let-closure/ + let-constructor, so we use a common structure and distinguish between them + with an @is_recursive@ boolean flag. + +- let-unboxed u = <an arbitrary arithmetic expression in unboxed values> in e + + All the stuff on the RHS must be fully evaluated. No function calls either! + + (We've backed away from this toward case-expressions with suitably-magical + alts ...) + +- Advanced stuff here! Not to start with, but makes pattern matching generate + more efficient code. + + let-escapes-not fail = expr + in e' + + Here the idea is that @e'@ guarantees not to put @fail@ in a data structure, + or pass it to another function. All @e'@ will ever do is tail-call @fail@. + Rather than build a closure for @fail@, all we need do is to record the stack + level at the moment of the @let-escapes-not@; then entering @fail@ is just a + matter of adjusting the stack pointer back down to that point and entering the + code for it. + + Another example: + + f x y = let z = huge-expression in + if y==1 then z else + if y==2 then z else + 1 + + (A let-escapes-not is an @StgLetNoEscape@.) + +- We may eventually want: + + let-literal x = Literal in e And so the code for let(rec)-things: -} @@ -382,11 +367,11 @@ And so the code for let(rec)-things: (GenStgExpr pass) -- body {- -%************************************************************************ -%* * -\subsubsection{@GenStgExpr@: @hpc@, @scc@ and other debug annotations} -%* * -%************************************************************************ +************************************************************************* +* * +GenStgExpr: hpc, scc and other debug annotations +* * +************************************************************************* Finally for @hpc@ expressions we introduce a new STG construct. -} @@ -400,12 +385,12 @@ Finally for @hpc@ expressions we introduce a new STG construct. {- ************************************************************************ * * -\subsection{STG right-hand sides} +STG right-hand sides * * ************************************************************************ -Here's the rest of the interesting stuff for @StgLet@s; the first -flavour is for closures: +Here's the rest of the interesting stuff for @StgLet@s; the first flavour is for +closures: -} data GenStgRhs pass @@ -420,18 +405,19 @@ data GenStgRhs pass {- An example may be in order. Consider: -\begin{verbatim} -let t = \x -> \y -> ... x ... y ... p ... q in e -\end{verbatim} + + let t = \x -> \y -> ... x ... y ... p ... q in e + Pulling out the free vars and stylising somewhat, we get the equivalent: -\begin{verbatim} -let t = (\[p,q] -> \[x,y] -> ... x ... y ... p ...q) p q -\end{verbatim} -Stg-operationally, the @[x,y]@ are on the stack, the @[p,q]@ are -offsets from @Node@ into the closure, and the code ptr for the closure -will be exactly that in parentheses above. - -The second flavour of right-hand-side is for constructors (simple but important): + + let t = (\[p,q] -> \[x,y] -> ... x ... y ... p ...q) p q + +Stg-operationally, the @[x,y]@ are on the stack, the @[p,q]@ are offsets from +@Node@ into the closure, and the code ptr for the closure will be exactly that +in parentheses above. + +The second flavour of right-hand-side is for constructors (simple but +important): -} | StgRhsCon @@ -569,20 +555,19 @@ stgIdHasCafRefs id = {- ************************************************************************ * * -\subsection[Stg-case-alternatives]{STG case alternatives} +STG case alternatives * * ************************************************************************ Very like in @CoreSyntax@ (except no type-world stuff). -The type constructor is guaranteed not to be abstract; that is, we can -see its representation. This is important because the code generator -uses it to determine return conventions etc. But it's not trivial -where there's a module loop involved, because some versions of a type -constructor might not have all the constructors visible. So -mkStgAlgAlts (in CoreToStg) ensures that it gets the TyCon from the -constructors or literals (which are guaranteed to have the Real McCoy) -rather than from the scrutinee type. +The type constructor is guaranteed not to be abstract; that is, we can see its +representation. This is important because the code generator uses it to +determine return conventions etc. But it's not trivial where there's a module +loop involved, because some versions of a type constructor might not have all +the constructors visible. So mkStgAlgAlts (in CoreToStg) ensures that it gets +the TyCon from the constructors or literals (which are guaranteed to have the +Real McCoy) rather than from the scrutinee type. -} type GenStgAlt pass @@ -601,7 +586,7 @@ data AltType {- ************************************************************************ * * -\subsection[Stg]{The Plain STG parameterisation} +The Plain STG parameterisation * * ************************************************************************ @@ -648,17 +633,16 @@ type OutStgAlt = StgAlt ************************************************************************ * * -\subsubsection[UpdateFlag-datatype]{@UpdateFlag@} +UpdateFlag * * ************************************************************************ This is also used in @LambdaFormInfo@ in the @ClosureInfo@ module. -A @ReEntrant@ closure may be entered multiple times, but should not be -updated or blackholed. An @Updatable@ closure should be updated after -evaluation (and may be blackholed during evaluation). A @SingleEntry@ -closure will only be entered once, and so need not be updated but may -safely be blackholed. +A @ReEntrant@ closure may be entered multiple times, but should not be updated +or blackholed. An @Updatable@ closure should be updated after evaluation (and +may be blackholed during evaluation). A @SingleEntry@ closure will only be +entered once, and so need not be updated but may safely be blackholed. -} data UpdateFlag = ReEntrant | Updatable | SingleEntry @@ -677,13 +661,12 @@ isUpdatable Updatable = True {- ************************************************************************ * * -\subsubsection{StgOp} +StgOp * * ************************************************************************ -An StgOp allows us to group together PrimOps and ForeignCalls. -It's quite useful to move these around together, notably -in StgOpApp and COpStmt. +An StgOp allows us to group together PrimOps and ForeignCalls. It's quite useful +to move these around together, notably in StgOpApp and COpStmt. -} data StgOp @@ -700,12 +683,12 @@ data StgOp {- ************************************************************************ * * -\subsection[Stg-pretty-printing]{Pretty-printing} +Pretty-printing * * ************************************************************************ -Robin Popplestone asked for semi-colon separators on STG binds; here's -hoping he likes terminators instead... Ditto for case alternatives. +Robin Popplestone asked for semi-colon separators on STG binds; here's hoping he +likes terminators instead... Ditto for case alternatives. -} type OutputablePass pass = |