summaryrefslogtreecommitdiff
path: root/compiler/GHC/Stg/Syntax.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Stg/Syntax.hs')
-rw-r--r--compiler/GHC/Stg/Syntax.hs98
1 files changed, 75 insertions, 23 deletions
diff --git a/compiler/GHC/Stg/Syntax.hs b/compiler/GHC/Stg/Syntax.hs
index b38c2f1ab0..37f834d2bb 100644
--- a/compiler/GHC/Stg/Syntax.hs
+++ b/compiler/GHC/Stg/Syntax.hs
@@ -3,7 +3,9 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
@@ -25,9 +27,11 @@ module GHC.Stg.Syntax (
GenStgTopBinding(..), GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),
GenStgAlt, AltType(..),
- StgPass(..), BinderP, XRhsClosure, XLet, XLetNoEscape,
+ StgPass(..), BinderP, XRhsClosure, XLet, XLetNoEscape, XXStgExpr,
+ StgPassWitness(..), IsStgPass,
NoExtFieldSilent, noExtFieldSilent,
OutputablePass,
+ StgLam(..),
UpdateFlag(..), isUpdatable,
@@ -40,6 +44,9 @@ module GHC.Stg.Syntax (
-- a set of synonyms for the lambda lifting parameterisation
LlStgTopBinding, LlStgBinding, LlStgExpr, LlStgRhs, LlStgAlt,
+ -- a set of synonyms for the core to stg parameterisation
+ SgStgTopBinding, SgStgBinding, SgStgExpr, SgStgRhs, SgStgAlt,
+
-- a set of synonyms to distinguish in- and out variants
InStgArg, InStgTopBinding, InStgBinding, InStgExpr, InStgRhs, InStgAlt,
OutStgArg, OutStgTopBinding, OutStgBinding, OutStgExpr, OutStgRhs, OutStgAlt,
@@ -73,6 +80,10 @@ import Data.Data ( Data )
import Data.List ( intersperse )
import GHC.Core.DataCon
import GHC.Driver.Session
+import GHC.Hs.Extension ( NoExtCon )
+#if __GLASGOW_HASKELL__ < 811
+import GHC.Hs.Extension ( noExtCon )
+#endif
import GHC.Types.ForeignCall ( ForeignCall )
import GHC.Types.Id
import GHC.Types.Name ( isDynLinkName )
@@ -256,22 +267,6 @@ literals.
{-
************************************************************************
* *
-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
- (NonEmpty (BinderP pass))
- StgExpr -- Body of lambda
-
-{-
-************************************************************************
-* *
GenStgExpr: case-expressions
* *
************************************************************************
@@ -386,6 +381,8 @@ Finally for @hpc@ expressions we introduce a new STG construct.
(Tickish Id)
(GenStgExpr pass) -- sub expression
+ | XStgExpr !(XXStgExpr pass)
+
-- END of GenStgExpr
{-
@@ -441,6 +438,28 @@ data StgPass
= Vanilla
| LiftLams
| CodeGen
+ | StgGen
+
+data StgPassWitness (pass :: StgPass) where
+ VanillaWitness :: StgPassWitness 'Vanilla
+ LiftLamsWitness :: StgPassWitness 'LiftLams
+ CodeGenWitness :: StgPassWitness 'CodeGen
+ StgGenWitness :: StgPassWitness 'StgGen
+
+class IsStgPass (pass :: StgPass) where
+ stgPass :: StgPassWitness pass
+
+instance IsStgPass 'Vanilla where
+ stgPass = VanillaWitness
+
+instance IsStgPass 'LiftLams where
+ stgPass = LiftLamsWitness
+
+instance IsStgPass 'CodeGen where
+ stgPass = CodeGenWitness
+
+instance IsStgPass 'StgGen where
+ stgPass = StgGenWitness
-- | Like 'GHC.Hs.Extension.NoExtField', but with an 'Outputable' instance that
-- returns 'empty'.
@@ -462,19 +481,37 @@ noExtFieldSilent = NoExtFieldSilent
type family BinderP (pass :: StgPass)
type instance BinderP 'Vanilla = Id
type instance BinderP 'CodeGen = Id
+type instance BinderP 'StgGen = Id
type family XRhsClosure (pass :: StgPass)
type instance XRhsClosure 'Vanilla = NoExtFieldSilent
-- | Code gen needs to track non-global free vars
type instance XRhsClosure 'CodeGen = DIdSet
+type instance XRhsClosure 'StgGen = NoExtFieldSilent
type family XLet (pass :: StgPass)
type instance XLet 'Vanilla = NoExtFieldSilent
type instance XLet 'CodeGen = NoExtFieldSilent
+type instance XLet 'StgGen = NoExtFieldSilent
type family XLetNoEscape (pass :: StgPass)
type instance XLetNoEscape 'Vanilla = NoExtFieldSilent
type instance XLetNoEscape 'CodeGen = NoExtFieldSilent
+type instance XLetNoEscape 'StgGen = NoExtFieldSilent
+
+type family XXStgExpr (pass :: StgPass)
+type instance XXStgExpr 'Vanilla = NoExtCon
+type instance XXStgExpr 'CodeGen = NoExtCon
+type instance XXStgExpr 'LiftLams = NoExtCon
+type instance XXStgExpr 'StgGen = StgLam
+
+-- StgLam is used *only* during CoreToStg's work. Before CoreToStg has finished
+-- it encodes (\x -> e) as (let f = \x -> e in f). We define this here rather
+-- than in CoreToStg because we need it for pretty-printing StgExpr and
+-- importing CoreToStg would create an import cycle.
+data StgLam = StgLam
+ (NonEmpty Id)
+ SgStgExpr
stgRhsArity :: StgRhs -> Int
stgRhsArity (StgRhsClosure _ _ _ bndrs _)
@@ -541,6 +578,12 @@ type CgStgExpr = GenStgExpr 'CodeGen
type CgStgRhs = GenStgRhs 'CodeGen
type CgStgAlt = GenStgAlt 'CodeGen
+type SgStgTopBinding = GenStgTopBinding 'StgGen
+type SgStgBinding = GenStgBinding 'StgGen
+type SgStgExpr = GenStgExpr 'StgGen
+type SgStgRhs = GenStgRhs 'StgGen
+type SgStgAlt = GenStgAlt 'StgGen
+
{- Many passes apply a substitution, and it's very handy to have type
synonyms to remind us whether or not the substitution has been applied.
See GHC.Core for precedence in Core land
@@ -645,6 +688,7 @@ type OutputablePass pass =
, Outputable (XLetNoEscape pass)
, Outputable (XRhsClosure pass)
, OutputableBndr (BinderP pass)
+ , IsStgPass pass
)
-- | STG pretty-printing options
@@ -701,7 +745,7 @@ pprStgArg :: StgArg -> SDoc
pprStgArg (StgVarArg var) = ppr var
pprStgArg (StgLitArg con) = ppr con
-pprStgExpr :: OutputablePass pass => StgPprOpts -> GenStgExpr pass -> SDoc
+pprStgExpr :: forall pass. OutputablePass pass => StgPprOpts -> GenStgExpr pass -> SDoc
pprStgExpr opts e = case e of
-- special case
StgLit lit -> ppr lit
@@ -709,11 +753,6 @@ pprStgExpr opts e = case e of
StgApp func args -> hang (ppr func) 4 (interppSP args)
StgConApp con args _ -> hsep [ ppr con, brackets (interppSP args) ]
StgOpApp op args _ -> hsep [ pprStgOp op, brackets (interppSP args)]
- StgLam bndrs body -> let ppr_list = brackets . fsep . punctuate comma
- in sep [ char '\\' <+> ppr_list (map (pprBndr LambdaBind) (toList bndrs))
- <+> text "->"
- , pprStgExpr opts body
- ]
-- special case: let v = <very specific thing>
-- in
@@ -786,6 +825,19 @@ pprStgExpr opts e = case e of
, char '}'
]
+ XStgExpr xStgExpr -> case stgPass @pass of
+#if __GLASGOW_HASKELL__ < 811
+ VanillaWitness -> noExtCon xStgExpr
+ LiftLamsWitness -> noExtCon xStgExpr
+ CodeGenWitness -> noExtCon xStgExpr
+#endif
+ StgGenWitness -> case xStgExpr of
+ StgLam bndrs body -> let ppr_list = brackets . fsep . punctuate comma
+ in sep [ char '\\' <+> ppr_list (map (pprBndr LambdaBind) (toList bndrs))
+ <+> text "->"
+ , pprStgExpr opts body
+ ]
+
pprStgAlt :: OutputablePass pass => StgPprOpts -> Bool -> GenStgAlt pass -> SDoc
pprStgAlt opts indent (con, params, expr)