summaryrefslogtreecommitdiff
path: root/compiler/stgSyn/StgSyn.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/stgSyn/StgSyn.hs')
-rw-r--r--compiler/stgSyn/StgSyn.hs104
1 files changed, 66 insertions, 38 deletions
diff --git a/compiler/stgSyn/StgSyn.hs b/compiler/stgSyn/StgSyn.hs
index 145c001046..5ba63e458c 100644
--- a/compiler/stgSyn/StgSyn.hs
+++ b/compiler/stgSyn/StgSyn.hs
@@ -16,6 +16,7 @@ generation.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE ConstraintKinds #-}
module StgSyn (
StgArg(..),
@@ -23,7 +24,8 @@ module StgSyn (
GenStgTopBinding(..), GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),
GenStgAlt, AltType(..),
- StgPass(..), XRhsClosure, NoExtSilent, noExtSilent,
+ StgPass(..), BinderP, XRhsClosure, XLet, XLetNoEscape,
+ NoExtSilent, noExtSilent,
UpdateFlag(..), isUpdatable,
@@ -33,6 +35,9 @@ module StgSyn (
-- a set of synonyms for the code gen parameterisation
CgStgTopBinding, CgStgBinding, CgStgExpr, CgStgRhs, CgStgAlt,
+ -- a set of synonyms for the lambda lifting parameterisation
+ LlStgTopBinding, LlStgBinding, LlStgExpr, LlStgRhs, LlStgAlt,
+
-- a set of synonyms to distinguish in- and out variants
InStgArg, InStgTopBinding, InStgBinding, InStgExpr, InStgRhs, InStgAlt,
OutStgArg, OutStgTopBinding, OutStgBinding, OutStgExpr, OutStgRhs, OutStgAlt,
@@ -101,8 +106,8 @@ data GenStgTopBinding pass
| StgTopStringLit Id ByteString
data GenStgBinding pass
- = StgNonRec Id (GenStgRhs pass)
- | StgRec [(Id, GenStgRhs pass)]
+ = StgNonRec (BinderP pass) (GenStgRhs pass)
+ | StgRec [(BinderP pass, GenStgRhs pass)]
{-
************************************************************************
@@ -245,7 +250,7 @@ TODO: Encode this via an extension to GenStgExpr à la TTG.
-}
| StgLam
- (NonEmpty Id)
+ (NonEmpty (BinderP pass))
StgExpr -- Body of lambda
{-
@@ -259,13 +264,9 @@ This has the same boxed/unboxed business as Core case expressions.
-}
| StgCase
- (GenStgExpr pass)
- -- the thing to examine
-
- Id -- binds the result of evaluating the scrutinee
-
+ (GenStgExpr pass) -- the thing to examine
+ (BinderP pass) -- binds the result of evaluating the scrutinee
AltType
-
[GenStgAlt pass]
-- The DEFAULT case is always *first*
-- if it is there at all
@@ -365,10 +366,12 @@ And so the code for let(rec)-things:
-}
| StgLet
+ (XLet pass)
(GenStgBinding pass) -- right hand sides (see below)
(GenStgExpr pass) -- body
| StgLetNoEscape
+ (XLetNoEscape pass)
(GenStgBinding pass) -- right hand sides (see below)
(GenStgExpr pass) -- body
@@ -405,7 +408,7 @@ data GenStgRhs pass
-- list just before 'CodeGen'.
CostCentreStack -- ^ CCS to be attached (default is CurrentCCS)
!UpdateFlag -- ^ 'ReEntrant' | 'Updatable' | 'SingleEntry'
- [Id] -- ^ arguments; if empty, then not a function;
+ [BinderP pass] -- ^ arguments; if empty, then not a function;
-- as above, order is important.
(GenStgExpr pass) -- ^ body
@@ -437,8 +440,9 @@ The second flavour of right-hand-side is for constructors (simple but important)
-- | Used as a data type index for the stgSyn AST
data StgPass
- = CodeGen
- | Vanilla
+ = Vanilla
+ | LiftLams
+ | CodeGen
-- | Like 'HsExpression.NoExt', but with an 'Outputable' instance that returns
-- 'empty'.
@@ -455,9 +459,24 @@ noExtSilent = NoExtSilent
-- TODO: Maybe move this to HsExtensions? I'm not sure about the implications
-- on build time...
-type family XRhsClosure (pass :: StgPass) where
- XRhsClosure 'CodeGen = IdSet -- code gen needs to track non-global free vars
- XRhsClosure 'Vanilla = NoExtSilent
+-- TODO: Do we really want to the extension point type families to have a closed
+-- domain?
+type family BinderP (pass :: StgPass)
+type instance BinderP 'Vanilla = Id
+type instance BinderP 'CodeGen = Id
+
+type family XRhsClosure (pass :: StgPass)
+type instance XRhsClosure 'Vanilla = NoExtSilent
+-- | Code gen needs to track non-global free vars
+type instance XRhsClosure 'CodeGen = DIdSet
+
+type family XLet (pass :: StgPass)
+type instance XLet 'Vanilla = NoExtSilent
+type instance XLet 'CodeGen = NoExtSilent
+
+type family XLetNoEscape (pass :: StgPass)
+type instance XLetNoEscape 'Vanilla = NoExtSilent
+type instance XLetNoEscape 'CodeGen = NoExtSilent
stgRhsArity :: StgRhs -> Int
stgRhsArity (StgRhsClosure _ _ _ bndrs _)
@@ -506,9 +525,9 @@ exprHasCafRefs (StgLam _ body)
= exprHasCafRefs body
exprHasCafRefs (StgCase scrt _ _ alts)
= exprHasCafRefs scrt || any altHasCafRefs alts
-exprHasCafRefs (StgLet bind body)
+exprHasCafRefs (StgLet _ bind body)
= bindHasCafRefs bind || exprHasCafRefs body
-exprHasCafRefs (StgLetNoEscape bind body)
+exprHasCafRefs (StgLetNoEscape _ bind body)
= bindHasCafRefs bind || exprHasCafRefs body
exprHasCafRefs (StgTick _ expr)
= exprHasCafRefs expr
@@ -562,7 +581,7 @@ rather than from the scrutinee type.
type GenStgAlt pass
= (AltCon, -- alts: data constructor,
- [Id], -- constructor's parameters,
+ [BinderP pass], -- constructor's parameters,
GenStgExpr pass) -- ...right-hand side.
data AltType
@@ -589,6 +608,12 @@ type StgExpr = GenStgExpr 'Vanilla
type StgRhs = GenStgRhs 'Vanilla
type StgAlt = GenStgAlt 'Vanilla
+type LlStgTopBinding = GenStgTopBinding 'LiftLams
+type LlStgBinding = GenStgBinding 'LiftLams
+type LlStgExpr = GenStgExpr 'LiftLams
+type LlStgRhs = GenStgRhs 'LiftLams
+type LlStgAlt = GenStgAlt 'LiftLams
+
type CgStgTopBinding = GenStgTopBinding 'CodeGen
type CgStgBinding = GenStgBinding 'CodeGen
type CgStgExpr = GenStgExpr 'CodeGen
@@ -676,8 +701,15 @@ Robin Popplestone asked for semi-colon separators on STG binds; here's
hoping he likes terminators instead... Ditto for case alternatives.
-}
+type OutputablePass pass =
+ ( Outputable (XLet pass)
+ , Outputable (XLetNoEscape pass)
+ , Outputable (XRhsClosure pass)
+ , OutputableBndr (BinderP pass)
+ )
+
pprGenStgTopBinding
- :: Outputable (XRhsClosure pass) => GenStgTopBinding pass -> SDoc
+ :: OutputablePass pass => GenStgTopBinding pass -> SDoc
pprGenStgTopBinding (StgTopStringLit bndr str)
= hang (hsep [pprBndr LetBind bndr, equals])
4 (pprHsBytes str <> semi)
@@ -685,7 +717,7 @@ pprGenStgTopBinding (StgTopLifted bind)
= pprGenStgBinding bind
pprGenStgBinding
- :: (Outputable (XRhsClosure pass)) => GenStgBinding pass -> SDoc
+ :: OutputablePass pass => GenStgBinding pass -> SDoc
pprGenStgBinding (StgNonRec bndr rhs)
= hang (hsep [pprBndr LetBind bndr, equals])
@@ -709,27 +741,23 @@ pprStgTopBindings binds
instance Outputable StgArg where
ppr = pprStgArg
-instance (Outputable (XRhsClosure pass))
- => Outputable (GenStgTopBinding pass) where
+instance OutputablePass pass => Outputable (GenStgTopBinding pass) where
ppr = pprGenStgTopBinding
-instance (Outputable (XRhsClosure pass))
- => Outputable (GenStgBinding pass) where
+instance OutputablePass pass => Outputable (GenStgBinding pass) where
ppr = pprGenStgBinding
-instance (Outputable (XRhsClosure pass))
- => Outputable (GenStgExpr pass) where
+instance OutputablePass pass => Outputable (GenStgExpr pass) where
ppr = pprStgExpr
-instance (Outputable (XRhsClosure pass))
- => Outputable (GenStgRhs pass) where
+instance OutputablePass pass => Outputable (GenStgRhs pass) where
ppr rhs = pprStgRhs rhs
pprStgArg :: StgArg -> SDoc
pprStgArg (StgVarArg var) = ppr var
pprStgArg (StgLitArg con) = ppr con
-pprStgExpr :: (Outputable (XRhsClosure pass)) => GenStgExpr pass -> SDoc
+pprStgExpr :: OutputablePass pass => GenStgExpr pass -> SDoc
-- special case
pprStgExpr (StgLit lit) = ppr lit
@@ -773,19 +801,19 @@ pprStgExpr (StgLet srt (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag a
-- special case: let ... in let ...
-pprStgExpr (StgLet bind expr@(StgLet _ _))
+pprStgExpr (StgLet ext bind expr@StgLet{})
= ($$)
- (sep [hang (text "let {")
+ (sep [hang (text "let" <+> ppr ext <+> text "{")
2 (hsep [pprGenStgBinding bind, text "} in"])])
(ppr expr)
-- general case
-pprStgExpr (StgLet bind expr)
- = sep [hang (text "let {") 2 (pprGenStgBinding bind),
+pprStgExpr (StgLet ext bind expr)
+ = sep [hang (text "let" <+> ppr ext <+> text "{") 2 (pprGenStgBinding bind),
hang (text "} in ") 2 (ppr expr)]
-pprStgExpr (StgLetNoEscape bind expr)
- = sep [hang (text "let-no-escape {")
+pprStgExpr (StgLetNoEscape ext bind expr)
+ = sep [hang (text "let-no-escape" <+> ppr ext <+> text "{")
2 (pprGenStgBinding bind),
hang (text "} in ")
2 (ppr expr)]
@@ -805,7 +833,7 @@ pprStgExpr (StgCase expr bndr alt_type alts)
nest 2 (vcat (map pprStgAlt alts)),
char '}']
-pprStgAlt :: (Outputable (XRhsClosure pass)) => GenStgAlt pass -> SDoc
+pprStgAlt :: OutputablePass pass => GenStgAlt pass -> SDoc
pprStgAlt (con, params, expr)
= hang (hsep [ppr con, sep (map (pprBndr CasePatBind) params), text "->"])
4 (ppr expr <> semi)
@@ -821,7 +849,7 @@ instance Outputable AltType where
ppr (AlgAlt tc) = text "Alg" <+> ppr tc
ppr (PrimAlt tc) = text "Prim" <+> ppr tc
-pprStgRhs :: (Outputable (XRhsClosure pass)) => GenStgRhs pass -> SDoc
+pprStgRhs :: OutputablePass pass => GenStgRhs pass -> SDoc
-- special case
pprStgRhs (StgRhsClosure ext cc upd_flag [{-no args-}] (StgApp func []))