{-# LANGUAGE CPP, DeriveFunctor #-}
module GHC.CoreToStg ( coreToStg ) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Core
import GHC.Core.Utils ( exprType, findDefault, isJoinBind
, exprIsTickedString_maybe )
import GHC.Core.Opt.Arity ( manifestArity )
import GHC.Stg.Syntax
import GHC.Core.Type
import GHC.Types.RepType
import GHC.Core.TyCon
import GHC.Types.Id.Make ( coercionTokenId )
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Core.DataCon
import GHC.Types.CostCentre
import GHC.Types.Var.Env
import GHC.Unit.Module
import GHC.Types.Name ( isExternalName, nameModule_maybe )
import GHC.Types.Basic ( Arity )
import GHC.Builtin.Types ( unboxedUnitDataCon, unitDataConId )
import GHC.Types.Literal
import GHC.Utils.Outputable
import GHC.Utils.Monad
import GHC.Data.FastString
import GHC.Utils.Misc
import GHC.Driver.Session
import GHC.Driver.Ways
import GHC.Types.ForeignCall
import GHC.Types.Demand ( isUsedOnce )
import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId )
import GHC.Types.SrcLoc ( mkGeneralSrcSpan )
import GHC.Builtin.Names ( unsafeEqualityProofName )
import Data.List.NonEmpty (nonEmpty, toList)
import Data.Maybe (fromMaybe)
import Control.Monad (ap)
import qualified Data.Set as Set
coreToStg :: DynFlags -> Module -> CoreProgram
-> ([StgTopBinding], CollectedCCs)
coreToStg :: DynFlags
-> Module -> CoreProgram -> ([StgTopBinding], CollectedCCs)
coreToStg DynFlags
dflags Module
this_mod CoreProgram
pgm
= ([StgTopBinding]
pgm', CollectedCCs
final_ccs)
where
(IdEnv HowBound
_, ([CostCentre]
local_ccs, [CostCentreStack]
local_cc_stacks), [StgTopBinding]
pgm')
= DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
forall a. VarEnv a
emptyVarEnv CollectedCCs
emptyCollectedCCs CoreProgram
pgm
prof :: Bool
prof = Way
WayProf Way -> Set Way -> Bool
forall a. Ord a => a -> Set a -> Bool
External instance of the constraint type Ord Way
`Set.member` DynFlags -> Set Way
ways DynFlags
dflags
final_ccs :: CollectedCCs
final_ccs
| Bool
prof Bool -> Bool -> Bool
&& GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_AutoSccsOnIndividualCafs DynFlags
dflags
= ([CostCentre]
local_ccs,[CostCentreStack]
local_cc_stacks)
| Bool
prof
= (CostCentre
all_cafs_ccCostCentre -> [CostCentre] -> [CostCentre]
forall a. a -> [a] -> [a]
:[CostCentre]
local_ccs, CostCentreStack
all_cafs_ccsCostCentreStack -> [CostCentreStack] -> [CostCentreStack]
forall a. a -> [a] -> [a]
:[CostCentreStack]
local_cc_stacks)
| Bool
otherwise
= CollectedCCs
emptyCollectedCCs
(CostCentre
all_cafs_cc, CostCentreStack
all_cafs_ccs) = Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod
coreTopBindsToStg
:: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg :: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
_ Module
_ IdEnv HowBound
env CollectedCCs
ccs []
= (IdEnv HowBound
env, CollectedCCs
ccs, [])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (CoreBind
b:CoreProgram
bs)
= (IdEnv HowBound
env2, CollectedCCs
ccs2, StgTopBinding
b'StgTopBinding -> [StgTopBinding] -> [StgTopBinding]
forall a. a -> [a] -> [a]
:[StgTopBinding]
bs')
where
(IdEnv HowBound
env1, CollectedCCs
ccs1, StgTopBinding
b' ) =
DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs CoreBind
b
(IdEnv HowBound
env2, CollectedCCs
ccs2, [StgTopBinding]
bs') =
DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreProgram
-> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
coreTopBindsToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env1 CollectedCCs
ccs1 CoreProgram
bs
coreTopBindToStg
:: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg :: DynFlags
-> Module
-> IdEnv HowBound
-> CollectedCCs
-> CoreBind
-> (IdEnv HowBound, CollectedCCs, StgTopBinding)
coreTopBindToStg DynFlags
_ Module
_ IdEnv HowBound
env CollectedCCs
ccs (NonRec Id
id CoreArg
e)
| Just ByteString
str <- CoreArg -> Maybe ByteString
exprIsTickedString_maybe CoreArg
e
= let
env' :: IdEnv HowBound
env' = IdEnv HowBound -> Id -> HowBound -> IdEnv HowBound
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv IdEnv HowBound
env Id
id HowBound
how_bound
how_bound :: HowBound
how_bound = LetInfo -> JoinArity -> HowBound
LetBound LetInfo
TopLet JoinArity
0
in (IdEnv HowBound
env', CollectedCCs
ccs, Id -> ByteString -> StgTopBinding
forall (pass :: StgPass). Id -> ByteString -> GenStgTopBinding pass
StgTopStringLit Id
id ByteString
str)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (NonRec Id
id CoreArg
rhs)
= let
env' :: IdEnv HowBound
env' = IdEnv HowBound -> Id -> HowBound -> IdEnv HowBound
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv IdEnv HowBound
env Id
id HowBound
how_bound
how_bound :: HowBound
how_bound = LetInfo -> JoinArity -> HowBound
LetBound LetInfo
TopLet (JoinArity -> HowBound) -> JoinArity -> HowBound
forall a b. (a -> b) -> a -> b
$! CoreArg -> JoinArity
manifestArity CoreArg
rhs
(StgRhs
stg_rhs, CollectedCCs
ccs') =
DynFlags
-> IdEnv HowBound
-> CtsM (StgRhs, CollectedCCs)
-> (StgRhs, CollectedCCs)
forall a. DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env (CtsM (StgRhs, CollectedCCs) -> (StgRhs, CollectedCCs))
-> CtsM (StgRhs, CollectedCCs) -> (StgRhs, CollectedCCs)
forall a b. (a -> b) -> a -> b
$
DynFlags
-> CollectedCCs
-> Module
-> (Id, CoreArg)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (Id
id,CoreArg
rhs)
bind :: StgTopBinding
bind = GenStgBinding 'Vanilla -> StgTopBinding
forall (pass :: StgPass).
GenStgBinding pass -> GenStgTopBinding pass
StgTopLifted (GenStgBinding 'Vanilla -> StgTopBinding)
-> GenStgBinding 'Vanilla -> StgTopBinding
forall a b. (a -> b) -> a -> b
$ BinderP 'Vanilla -> StgRhs -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
BinderP pass -> GenStgRhs pass -> GenStgBinding pass
StgNonRec Id
BinderP 'Vanilla
id StgRhs
stg_rhs
in
(IdEnv HowBound
env', CollectedCCs
ccs', StgTopBinding
bind)
coreTopBindToStg DynFlags
dflags Module
this_mod IdEnv HowBound
env CollectedCCs
ccs (Rec [(Id, CoreArg)]
pairs)
= ASSERT( not (null pairs) )
let
binders :: [Id]
binders = ((Id, CoreArg) -> Id) -> [(Id, CoreArg)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreArg) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreArg)]
pairs
extra_env' :: [(Id, HowBound)]
extra_env' = [ (Id
b, LetInfo -> JoinArity -> HowBound
LetBound LetInfo
TopLet (JoinArity -> HowBound) -> JoinArity -> HowBound
forall a b. (a -> b) -> a -> b
$! CoreArg -> JoinArity
manifestArity CoreArg
rhs)
| (Id
b, CoreArg
rhs) <- [(Id, CoreArg)]
pairs ]
env' :: IdEnv HowBound
env' = IdEnv HowBound -> [(Id, HowBound)] -> IdEnv HowBound
forall a. VarEnv a -> [(Id, a)] -> VarEnv a
extendVarEnvList IdEnv HowBound
env [(Id, HowBound)]
extra_env'
(CollectedCCs
ccs', [StgRhs]
stg_rhss)
= DynFlags
-> IdEnv HowBound
-> CtsM (CollectedCCs, [StgRhs])
-> (CollectedCCs, [StgRhs])
forall a. DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env' (CtsM (CollectedCCs, [StgRhs]) -> (CollectedCCs, [StgRhs]))
-> CtsM (CollectedCCs, [StgRhs]) -> (CollectedCCs, [StgRhs])
forall a b. (a -> b) -> a -> b
$ do
(CollectedCCs -> (Id, CoreArg) -> CtsM (CollectedCCs, StgRhs))
-> CollectedCCs -> [(Id, CoreArg)] -> CtsM (CollectedCCs, [StgRhs])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
Instance of class: Monad of the constraint type Monad CtsM
mapAccumLM (\CollectedCCs
ccs (Id, CoreArg)
rhs -> do
(StgRhs
rhs', CollectedCCs
ccs') <-
DynFlags
-> CollectedCCs
-> Module
-> (Id, CoreArg)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (Id, CoreArg)
rhs
(CollectedCCs, StgRhs) -> CtsM (CollectedCCs, StgRhs)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (CollectedCCs
ccs', StgRhs
rhs'))
CollectedCCs
ccs
[(Id, CoreArg)]
pairs
bind :: StgTopBinding
bind = GenStgBinding 'Vanilla -> StgTopBinding
forall (pass :: StgPass).
GenStgBinding pass -> GenStgTopBinding pass
StgTopLifted (GenStgBinding 'Vanilla -> StgTopBinding)
-> GenStgBinding 'Vanilla -> StgTopBinding
forall a b. (a -> b) -> a -> b
$ [(BinderP 'Vanilla, StgRhs)] -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
[(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
StgRec ([Id] -> [StgRhs] -> [(Id, StgRhs)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Id]
binders [StgRhs]
stg_rhss)
in
(IdEnv HowBound
env', CollectedCCs
ccs', StgTopBinding
bind)
coreToTopStgRhs
:: DynFlags
-> CollectedCCs
-> Module
-> (Id,CoreExpr)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs :: DynFlags
-> CollectedCCs
-> Module
-> (Id, CoreArg)
-> CtsM (StgRhs, CollectedCCs)
coreToTopStgRhs DynFlags
dflags CollectedCCs
ccs Module
this_mod (Id
bndr, CoreArg
rhs)
= do { GenStgExpr 'Vanilla
new_rhs <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
rhs
; let (StgRhs
stg_rhs, CollectedCCs
ccs') =
DynFlags
-> Module
-> CollectedCCs
-> Id
-> GenStgExpr 'Vanilla
-> (StgRhs, CollectedCCs)
mkTopStgRhs DynFlags
dflags Module
this_mod CollectedCCs
ccs Id
bndr GenStgExpr 'Vanilla
new_rhs
stg_arity :: JoinArity
stg_arity =
StgRhs -> JoinArity
stgRhsArity StgRhs
stg_rhs
; (StgRhs, CollectedCCs) -> CtsM (StgRhs, CollectedCCs)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (ASSERT2( arity_ok stg_arity, mk_arity_msg stg_arity) stg_rhs,
CollectedCCs
ccs') }
where
arity_ok :: JoinArity -> Bool
arity_ok JoinArity
stg_arity
| Name -> Bool
isExternalName (Id -> Name
idName Id
bndr) = JoinArity
id_arity JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq JoinArity
== JoinArity
stg_arity
| Bool
otherwise = Bool
True
id_arity :: JoinArity
id_arity = Id -> JoinArity
idArity Id
bndr
mk_arity_msg :: a -> SDoc
mk_arity_msg a
stg_arity
= [SDoc] -> SDoc
vcat [Id -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type Outputable Id
ppr Id
bndr,
String -> SDoc
text String
"Id arity:" SDoc -> SDoc -> SDoc
<+> JoinArity -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type Outputable JoinArity
ppr JoinArity
id_arity,
String -> SDoc
text String
"STG arity:" SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall {a}. Outputable a => a -> SDoc
Evidence bound by a type signature of the constraint type Outputable a
ppr a
stg_arity]
coreToStgExpr
:: CoreExpr
-> CtsM StgExpr
coreToStgExpr :: CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr (Lit (LitNumber LitNumType
LitNumInteger Integer
_ Type
_)) = String -> CtsM (GenStgExpr 'Vanilla)
forall a. String -> a
panic String
"coreToStgExpr: LitInteger"
coreToStgExpr (Lit (LitNumber LitNumType
LitNumNatural Integer
_ Type
_)) = String -> CtsM (GenStgExpr 'Vanilla)
forall a. String -> a
panic String
"coreToStgExpr: LitNatural"
coreToStgExpr (Lit Literal
l) = GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (Literal -> GenStgExpr 'Vanilla
forall (pass :: StgPass). Literal -> GenStgExpr pass
StgLit Literal
l)
coreToStgExpr (App (Lit Literal
LitRubbish) CoreArg
_some_unlifted_type)
= CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr (Id -> CoreArg
forall b. Id -> Expr b
Var Id
unitDataConId)
coreToStgExpr (Var Id
v) = Id -> [CoreArg] -> [Tickish Id] -> CtsM (GenStgExpr 'Vanilla)
coreToStgApp Id
v [] []
coreToStgExpr (Coercion Coercion
_)
= Id -> [CoreArg] -> [Tickish Id] -> CtsM (GenStgExpr 'Vanilla)
coreToStgApp Id
coercionTokenId [] []
coreToStgExpr expr :: CoreArg
expr@(App CoreArg
_ CoreArg
_)
= Id -> [CoreArg] -> [Tickish Id] -> CtsM (GenStgExpr 'Vanilla)
coreToStgApp Id
f [CoreArg]
args [Tickish Id]
ticks
where
(Id
f, [CoreArg]
args, [Tickish Id]
ticks) = CoreArg -> (Id, [CoreArg], [Tickish Id])
myCollectArgs CoreArg
expr
coreToStgExpr expr :: CoreArg
expr@(Lam Id
_ CoreArg
_)
= let
([Id]
args, CoreArg
body) = CoreArg -> ([Id], CoreArg)
myCollectBinders CoreArg
expr
args' :: [Id]
args' = [Id] -> [Id]
filterStgBinders [Id]
args
in
[(Id, HowBound)]
-> CtsM (GenStgExpr 'Vanilla) -> CtsM (GenStgExpr 'Vanilla)
forall a. [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [ (Id
a, HowBound
LambdaBound) | Id
a <- [Id]
args' ] (CtsM (GenStgExpr 'Vanilla) -> CtsM (GenStgExpr 'Vanilla))
-> CtsM (GenStgExpr 'Vanilla) -> CtsM (GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ do
GenStgExpr 'Vanilla
body' <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
body
let
result_expr :: GenStgExpr 'Vanilla
result_expr = case [Id] -> Maybe (NonEmpty Id)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Id]
args' of
Maybe (NonEmpty Id)
Nothing -> GenStgExpr 'Vanilla
body'
Just NonEmpty Id
args'' -> NonEmpty (BinderP 'Vanilla)
-> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
NonEmpty (BinderP pass) -> GenStgExpr 'Vanilla -> GenStgExpr pass
StgLam NonEmpty Id
NonEmpty (BinderP 'Vanilla)
args'' GenStgExpr 'Vanilla
body'
GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return GenStgExpr 'Vanilla
result_expr
coreToStgExpr (Tick Tickish Id
tick CoreArg
expr)
= do case Tickish Id
tick of
HpcTick{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ()
ProfNote{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ()
SourceNote{} -> () -> CtsM ()
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ()
Breakpoint{} -> String -> CtsM ()
forall a. String -> a
panic String
"coreToStgExpr: breakpoint should not happen"
GenStgExpr 'Vanilla
expr2 <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
expr
GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (Tickish Id -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (pass :: StgPass).
Tickish Id -> GenStgExpr pass -> GenStgExpr pass
StgTick Tickish Id
tick GenStgExpr 'Vanilla
expr2)
coreToStgExpr (Cast CoreArg
expr Coercion
_)
= CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
expr
coreToStgExpr (Case CoreArg
scrut Id
_ Type
_ [])
= CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
scrut
coreToStgExpr e0 :: CoreArg
e0@(Case CoreArg
scrut Id
bndr Type
_ [Alt Id]
alts) = do
[(AltCon, [Id], GenStgExpr 'Vanilla)]
alts2 <- [(Id, HowBound)]
-> CtsM [(AltCon, [Id], GenStgExpr 'Vanilla)]
-> CtsM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall a. [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(Id
bndr, HowBound
LambdaBound)] ((Alt Id -> CtsM (AltCon, [Id], GenStgExpr 'Vanilla))
-> [Alt Id] -> CtsM [(AltCon, [Id], GenStgExpr 'Vanilla)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
Instance of class: Monad of the constraint type Monad CtsM
External instance of the constraint type Traversable []
mapM Alt Id -> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
vars_alt [Alt Id]
alts)
GenStgExpr 'Vanilla
scrut2 <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
scrut
let stg :: GenStgExpr 'Vanilla
stg = GenStgExpr 'Vanilla
-> BinderP 'Vanilla
-> AltType
-> [GenStgAlt 'Vanilla]
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
GenStgExpr pass
-> BinderP pass -> AltType -> [GenStgAlt pass] -> GenStgExpr pass
StgCase GenStgExpr 'Vanilla
scrut2 Id
BinderP 'Vanilla
bndr (Id -> [Alt Id] -> AltType
mkStgAltType Id
bndr [Alt Id]
alts) [(AltCon, [Id], GenStgExpr 'Vanilla)]
[GenStgAlt 'Vanilla]
alts2
case GenStgExpr 'Vanilla
scrut2 of
StgApp Id
id [] | Id -> Name
idName Id
id Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq Name
== Name
unsafeEqualityProofName ->
case [(AltCon, [Id], GenStgExpr 'Vanilla)]
alts2 of
[(AltCon
_, [Id
_co], GenStgExpr 'Vanilla
rhs)] ->
GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return GenStgExpr 'Vanilla
rhs
[(AltCon, [Id], GenStgExpr 'Vanilla)]
_ ->
String -> SDoc -> CtsM (GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStgExpr" (SDoc -> CtsM (GenStgExpr 'Vanilla))
-> SDoc -> CtsM (GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$
String -> SDoc
text String
"Unexpected unsafe equality case expression:" SDoc -> SDoc -> SDoc
$$ CoreArg -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall b. OutputableBndr b => Outputable (Expr b)
External instance of the constraint type OutputableBndr Id
ppr CoreArg
e0 SDoc -> SDoc -> SDoc
$$
String -> SDoc
text String
"STG:" SDoc -> SDoc -> SDoc
$$ GenStgExpr 'Vanilla -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall (pass :: StgPass).
OutputablePass pass =>
Outputable (GenStgExpr pass)
External instance of the constraint type Outputable NoExtFieldSilent
External instance of the constraint type Outputable NoExtFieldSilent
External instance of the constraint type Outputable NoExtFieldSilent
External instance of the constraint type OutputableBndr Id
ppr GenStgExpr 'Vanilla
stg
GenStgExpr 'Vanilla
_ -> GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return GenStgExpr 'Vanilla
stg
where
vars_alt :: (AltCon, [Var], CoreExpr) -> CtsM (AltCon, [Var], StgExpr)
vars_alt :: Alt Id -> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
vars_alt (AltCon
con, [Id]
binders, CoreArg
rhs)
| DataAlt DataCon
c <- AltCon
con, DataCon
c DataCon -> DataCon -> Bool
forall a. Eq a => a -> a -> Bool
External instance of the constraint type Eq DataCon
== DataCon
unboxedUnitDataCon
=
ASSERT( null binders )
do { GenStgExpr 'Vanilla
rhs2 <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
rhs
; (AltCon, [Id], GenStgExpr 'Vanilla)
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (AltCon
DEFAULT, [], GenStgExpr 'Vanilla
rhs2) }
| Bool
otherwise
= let
binders' :: [Id]
binders' = [Id] -> [Id]
filterStgBinders [Id]
binders
in
[(Id, HowBound)]
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
forall a. [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(Id
b, HowBound
LambdaBound) | Id
b <- [Id]
binders'] (CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla))
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ do
GenStgExpr 'Vanilla
rhs2 <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
rhs
(AltCon, [Id], GenStgExpr 'Vanilla)
-> CtsM (AltCon, [Id], GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (AltCon
con, [Id]
binders', GenStgExpr 'Vanilla
rhs2)
coreToStgExpr (Let CoreBind
bind CoreArg
body) = do
CoreBind -> CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgLet CoreBind
bind CoreArg
body
coreToStgExpr CoreArg
e = String -> SDoc -> CtsM (GenStgExpr 'Vanilla)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStgExpr" (CoreArg -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall b. OutputableBndr b => Outputable (Expr b)
External instance of the constraint type OutputableBndr Id
ppr CoreArg
e)
mkStgAltType :: Id -> [CoreAlt] -> AltType
mkStgAltType :: Id -> [Alt Id] -> AltType
mkStgAltType Id
bndr [Alt Id]
alts
| Type -> Bool
isUnboxedTupleType Type
bndr_ty Bool -> Bool -> Bool
|| Type -> Bool
isUnboxedSumType Type
bndr_ty
= JoinArity -> AltType
MultiValAlt ([PrimRep] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
External instance of the constraint type Foldable []
length [PrimRep]
prim_reps)
| Bool
otherwise
= case [PrimRep]
prim_reps of
[PrimRep
LiftedRep] -> case Type -> Maybe TyCon
tyConAppTyCon_maybe (Type -> Type
unwrapType Type
bndr_ty) of
Just TyCon
tc
| TyCon -> Bool
isAbstractTyCon TyCon
tc -> AltType
look_for_better_tycon
| TyCon -> Bool
isAlgTyCon TyCon
tc -> TyCon -> AltType
AlgAlt TyCon
tc
| Bool
otherwise -> ASSERT2( _is_poly_alt_tycon tc, ppr tc )
AltType
PolyAlt
Maybe TyCon
Nothing -> AltType
PolyAlt
[PrimRep
unlifted] -> PrimRep -> AltType
PrimAlt PrimRep
unlifted
[PrimRep]
not_unary -> JoinArity -> AltType
MultiValAlt ([PrimRep] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
External instance of the constraint type Foldable []
length [PrimRep]
not_unary)
where
bndr_ty :: Type
bndr_ty = Id -> Type
idType Id
bndr
prim_reps :: [PrimRep]
prim_reps = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
External instance of the constraint type HasDebugCallStack
typePrimRep Type
bndr_ty
_is_poly_alt_tycon :: TyCon -> Bool
_is_poly_alt_tycon TyCon
tc
= TyCon -> Bool
isFunTyCon TyCon
tc
Bool -> Bool -> Bool
|| TyCon -> Bool
isPrimTyCon TyCon
tc
Bool -> Bool -> Bool
|| TyCon -> Bool
isFamilyTyCon TyCon
tc
look_for_better_tycon :: AltType
look_for_better_tycon
| ((DataAlt DataCon
con, [Id]
_, CoreArg
_) : [Alt Id]
_) <- [Alt Id]
data_alts =
TyCon -> AltType
AlgAlt (DataCon -> TyCon
dataConTyCon DataCon
con)
| Bool
otherwise =
ASSERT(null data_alts)
AltType
PolyAlt
where
([Alt Id]
data_alts, Maybe CoreArg
_deflt) = [Alt Id] -> ([Alt Id], Maybe CoreArg)
forall a b. [(AltCon, [a], b)] -> ([(AltCon, [a], b)], Maybe b)
findDefault [Alt Id]
alts
coreToStgApp :: Id
-> [CoreArg]
-> [Tickish Id]
-> CtsM StgExpr
coreToStgApp :: Id -> [CoreArg] -> [Tickish Id] -> CtsM (GenStgExpr 'Vanilla)
coreToStgApp Id
f [CoreArg]
args [Tickish Id]
ticks = do
([StgArg]
args', [Tickish Id]
ticks') <- [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs [CoreArg]
args
HowBound
how_bound <- Id -> CtsM HowBound
lookupVarCts Id
f
let
n_val_args :: JoinArity
n_val_args = [CoreArg] -> JoinArity
forall b. [Arg b] -> JoinArity
valArgCount [CoreArg]
args
f_arity :: JoinArity
f_arity = Id -> HowBound -> JoinArity
stgArity Id
f HowBound
how_bound
saturated :: Bool
saturated = JoinArity
f_arity JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
External instance of the constraint type Ord JoinArity
<= JoinArity
n_val_args
res_ty :: Type
res_ty = CoreArg -> Type
exprType (CoreArg -> [CoreArg] -> CoreArg
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreArg
forall b. Id -> Expr b
Var Id
f) [CoreArg]
args)
app :: GenStgExpr pass
app = case Id -> IdDetails
idDetails Id
f of
DataConWorkId DataCon
dc
| Bool
saturated -> DataCon -> [StgArg] -> [Type] -> GenStgExpr pass
forall (pass :: StgPass).
DataCon -> [StgArg] -> [Type] -> GenStgExpr pass
StgConApp DataCon
dc [StgArg]
args'
([Type] -> [Type]
dropRuntimeRepArgs ([Type] -> Maybe [Type] -> [Type]
forall a. a -> Maybe a -> a
fromMaybe [] (Type -> Maybe [Type]
tyConAppArgs_maybe Type
res_ty)))
PrimOpId PrimOp
op
| Bool
saturated -> StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (PrimOp -> StgOp
StgPrimOp PrimOp
op) [StgArg]
args' Type
res_ty
| Bool
otherwise -> Id -> [StgArg] -> GenStgExpr pass
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp (PrimOp -> Id
primOpWrapperId PrimOp
op) [StgArg]
args'
FCallId (CCall (CCallSpec (StaticTarget SourceText
_ CLabelString
lbl (Just Unit
pkgId) Bool
True)
CCallConv
PrimCallConv Safety
_))
-> ASSERT( saturated )
StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (PrimCall -> StgOp
StgPrimCallOp (CLabelString -> Unit -> PrimCall
PrimCall CLabelString
lbl Unit
pkgId)) [StgArg]
args' Type
res_ty
FCallId ForeignCall
call -> ASSERT( saturated )
StgOp -> [StgArg] -> Type -> GenStgExpr pass
forall (pass :: StgPass).
StgOp -> [StgArg] -> Type -> GenStgExpr pass
StgOpApp (ForeignCall -> Type -> StgOp
StgFCallOp ForeignCall
call (Id -> Type
idType Id
f)) [StgArg]
args' Type
res_ty
TickBoxOpId {} -> String -> SDoc -> GenStgExpr pass
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStg TickBox" (SDoc -> GenStgExpr pass) -> SDoc -> GenStgExpr pass
forall a b. (a -> b) -> a -> b
$ (Id, [StgArg]) -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall a b. (Outputable a, Outputable b) => Outputable (a, b)
External instance of the constraint type Outputable Id
External instance of the constraint type forall a. Outputable a => Outputable [a]
External instance of the constraint type Outputable StgArg
ppr (Id
f,[StgArg]
args')
IdDetails
_other -> Id -> [StgArg] -> GenStgExpr pass
forall (pass :: StgPass). Id -> [StgArg] -> GenStgExpr pass
StgApp Id
f [StgArg]
args'
tapp :: GenStgExpr pass
tapp = (Tickish Id -> GenStgExpr pass -> GenStgExpr pass)
-> GenStgExpr pass -> [Tickish Id] -> GenStgExpr pass
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
External instance of the constraint type Foldable []
foldr Tickish Id -> GenStgExpr pass -> GenStgExpr pass
forall (pass :: StgPass).
Tickish Id -> GenStgExpr pass -> GenStgExpr pass
StgTick GenStgExpr pass
forall {pass :: StgPass}. GenStgExpr pass
app ([Tickish Id]
ticks [Tickish Id] -> [Tickish Id] -> [Tickish Id]
forall a. [a] -> [a] -> [a]
++ [Tickish Id]
ticks')
GenStgExpr Any
forall {pass :: StgPass}. GenStgExpr pass
app GenStgExpr Any
-> CtsM (GenStgExpr 'Vanilla) -> CtsM (GenStgExpr 'Vanilla)
`seq` GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return GenStgExpr 'Vanilla
forall {pass :: StgPass}. GenStgExpr pass
tapp
coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs :: [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs []
= ([StgArg], [Tickish Id]) -> CtsM ([StgArg], [Tickish Id])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ([], [])
coreToStgArgs (Type Type
_ : [CoreArg]
args) = do
([StgArg]
args', [Tickish Id]
ts) <- [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs [CoreArg]
args
([StgArg], [Tickish Id]) -> CtsM ([StgArg], [Tickish Id])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ([StgArg]
args', [Tickish Id]
ts)
coreToStgArgs (Coercion Coercion
_ : [CoreArg]
args)
= do { ([StgArg]
args', [Tickish Id]
ts) <- [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs [CoreArg]
args
; ([StgArg], [Tickish Id]) -> CtsM ([StgArg], [Tickish Id])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (Id -> StgArg
StgVarArg Id
coercionTokenId StgArg -> [StgArg] -> [StgArg]
forall a. a -> [a] -> [a]
: [StgArg]
args', [Tickish Id]
ts) }
coreToStgArgs (Tick Tickish Id
t CoreArg
e : [CoreArg]
args)
= ASSERT( not (tickishIsCode t) )
do { ([StgArg]
args', [Tickish Id]
ts) <- [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs (CoreArg
e CoreArg -> [CoreArg] -> [CoreArg]
forall a. a -> [a] -> [a]
: [CoreArg]
args)
; ([StgArg], [Tickish Id]) -> CtsM ([StgArg], [Tickish Id])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ([StgArg]
args', Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ts) }
coreToStgArgs (CoreArg
arg : [CoreArg]
args) = do
([StgArg]
stg_args, [Tickish Id]
ticks) <- [CoreArg] -> CtsM ([StgArg], [Tickish Id])
coreToStgArgs [CoreArg]
args
GenStgExpr 'Vanilla
arg' <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
arg
let
([Tickish Id]
aticks, GenStgExpr 'Vanilla
arg'') = (Tickish Id -> Bool)
-> GenStgExpr 'Vanilla -> ([Tickish Id], GenStgExpr 'Vanilla)
forall (p :: StgPass).
(Tickish Id -> Bool)
-> GenStgExpr p -> ([Tickish Id], GenStgExpr p)
stripStgTicksTop Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable GenStgExpr 'Vanilla
arg'
stg_arg :: StgArg
stg_arg = case GenStgExpr 'Vanilla
arg'' of
StgApp Id
v [] -> Id -> StgArg
StgVarArg Id
v
StgConApp DataCon
con [] [Type]
_ -> Id -> StgArg
StgVarArg (DataCon -> Id
dataConWorkId DataCon
con)
StgLit Literal
lit -> Literal -> StgArg
StgLitArg Literal
lit
GenStgExpr 'Vanilla
_ -> String -> SDoc -> StgArg
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"coreToStgArgs" (CoreArg -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall b. OutputableBndr b => Outputable (Expr b)
External instance of the constraint type OutputableBndr Id
ppr CoreArg
arg)
Platform
platform <- DynFlags -> Platform
targetPlatform (DynFlags -> Platform) -> CtsM DynFlags -> CtsM Platform
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Instance of class: Functor of the constraint type Functor CtsM
<$> CtsM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
Instance of class: HasDynFlags of the constraint type HasDynFlags CtsM
getDynFlags
let
arg_rep :: [PrimRep]
arg_rep = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
External instance of the constraint type HasDebugCallStack
typePrimRep (CoreArg -> Type
exprType CoreArg
arg)
stg_arg_rep :: [PrimRep]
stg_arg_rep = HasDebugCallStack => Type -> [PrimRep]
Type -> [PrimRep]
External instance of the constraint type HasDebugCallStack
typePrimRep (StgArg -> Type
stgArgType StgArg
stg_arg)
bad_args :: Bool
bad_args = Bool -> Bool
not (Platform -> [PrimRep] -> [PrimRep] -> Bool
primRepsCompatible Platform
platform [PrimRep]
arg_rep [PrimRep]
stg_arg_rep)
WARN( bad_args, text "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" $$ ppr arg )
([StgArg], [Tickish Id]) -> CtsM ([StgArg], [Tickish Id])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (StgArg
stg_arg StgArg -> [StgArg] -> [StgArg]
forall a. a -> [a] -> [a]
: [StgArg]
stg_args, [Tickish Id]
ticks [Tickish Id] -> [Tickish Id] -> [Tickish Id]
forall a. [a] -> [a] -> [a]
++ [Tickish Id]
aticks)
coreToStgLet
:: CoreBind
-> CoreExpr
-> CtsM StgExpr
coreToStgLet :: CoreBind -> CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgLet CoreBind
bind CoreArg
body = do
(GenStgBinding 'Vanilla
bind2, GenStgExpr 'Vanilla
body2)
<- do
( GenStgBinding 'Vanilla
bind2, [(Id, HowBound)]
env_ext)
<- CoreBind -> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
vars_bind CoreBind
bind
[(Id, HowBound)]
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
forall a. [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(Id, HowBound)]
env_ext (CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla))
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
forall a b. (a -> b) -> a -> b
$ do
GenStgExpr 'Vanilla
body2 <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
body
(GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
-> CtsM (GenStgBinding 'Vanilla, GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (GenStgBinding 'Vanilla
bind2, GenStgExpr 'Vanilla
body2)
let
new_let :: GenStgExpr 'Vanilla
new_let | CoreBind -> Bool
isJoinBind CoreBind
bind = XLetNoEscape 'Vanilla
-> GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
XLetNoEscape pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLetNoEscape XLetNoEscape 'Vanilla
NoExtFieldSilent
noExtFieldSilent GenStgBinding 'Vanilla
bind2 GenStgExpr 'Vanilla
body2
| Bool
otherwise = XLet 'Vanilla
-> GenStgBinding 'Vanilla
-> GenStgExpr 'Vanilla
-> GenStgExpr 'Vanilla
forall (pass :: StgPass).
XLet pass
-> GenStgBinding pass -> GenStgExpr pass -> GenStgExpr pass
StgLet XLet 'Vanilla
NoExtFieldSilent
noExtFieldSilent GenStgBinding 'Vanilla
bind2 GenStgExpr 'Vanilla
body2
GenStgExpr 'Vanilla -> CtsM (GenStgExpr 'Vanilla)
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return GenStgExpr 'Vanilla
new_let
where
mk_binding :: a -> CoreArg -> (a, HowBound)
mk_binding a
binder CoreArg
rhs
= (a
binder, LetInfo -> JoinArity -> HowBound
LetBound LetInfo
NestedLet (CoreArg -> JoinArity
manifestArity CoreArg
rhs))
vars_bind :: CoreBind
-> CtsM (StgBinding,
[(Id, HowBound)])
vars_bind :: CoreBind -> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
vars_bind (NonRec Id
binder CoreArg
rhs) = do
StgRhs
rhs2 <- (Id, CoreArg) -> CtsM StgRhs
coreToStgRhs (Id
binder,CoreArg
rhs)
let
env_ext_item :: (Id, HowBound)
env_ext_item = Id -> CoreArg -> (Id, HowBound)
forall {a}. a -> CoreArg -> (a, HowBound)
mk_binding Id
binder CoreArg
rhs
(GenStgBinding 'Vanilla, [(Id, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (BinderP 'Vanilla -> StgRhs -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
BinderP pass -> GenStgRhs pass -> GenStgBinding pass
StgNonRec Id
BinderP 'Vanilla
binder StgRhs
rhs2, [(Id, HowBound)
env_ext_item])
vars_bind (Rec [(Id, CoreArg)]
pairs)
= let
binders :: [Id]
binders = ((Id, CoreArg) -> Id) -> [(Id, CoreArg)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreArg) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreArg)]
pairs
env_ext :: [(Id, HowBound)]
env_ext = [ Id -> CoreArg -> (Id, HowBound)
forall {a}. a -> CoreArg -> (a, HowBound)
mk_binding Id
b CoreArg
rhs
| (Id
b,CoreArg
rhs) <- [(Id, CoreArg)]
pairs ]
in
[(Id, HowBound)]
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
forall a. [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(Id, HowBound)]
env_ext (CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)]))
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
forall a b. (a -> b) -> a -> b
$ do
[StgRhs]
rhss2 <- ((Id, CoreArg) -> CtsM StgRhs) -> [(Id, CoreArg)] -> CtsM [StgRhs]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
Instance of class: Monad of the constraint type Monad CtsM
External instance of the constraint type Traversable []
mapM (Id, CoreArg) -> CtsM StgRhs
coreToStgRhs [(Id, CoreArg)]
pairs
(GenStgBinding 'Vanilla, [(Id, HowBound)])
-> CtsM (GenStgBinding 'Vanilla, [(Id, HowBound)])
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return ([(BinderP 'Vanilla, StgRhs)] -> GenStgBinding 'Vanilla
forall (pass :: StgPass).
[(BinderP pass, GenStgRhs pass)] -> GenStgBinding pass
StgRec ([Id]
binders [Id] -> [StgRhs] -> [(Id, StgRhs)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [StgRhs]
rhss2), [(Id, HowBound)]
env_ext)
coreToStgRhs :: (Id,CoreExpr)
-> CtsM StgRhs
coreToStgRhs :: (Id, CoreArg) -> CtsM StgRhs
coreToStgRhs (Id
bndr, CoreArg
rhs) = do
GenStgExpr 'Vanilla
new_rhs <- CoreArg -> CtsM (GenStgExpr 'Vanilla)
coreToStgExpr CoreArg
rhs
StgRhs -> CtsM StgRhs
forall (m :: * -> *) a. Monad m => a -> m a
Instance of class: Monad of the constraint type Monad CtsM
return (Id -> GenStgExpr 'Vanilla -> StgRhs
mkStgRhs Id
bndr GenStgExpr 'Vanilla
new_rhs)
mkTopStgRhs :: DynFlags -> Module -> CollectedCCs
-> Id -> StgExpr -> (StgRhs, CollectedCCs)
mkTopStgRhs :: DynFlags
-> Module
-> CollectedCCs
-> Id
-> GenStgExpr 'Vanilla
-> (StgRhs, CollectedCCs)
mkTopStgRhs DynFlags
dflags Module
this_mod CollectedCCs
ccs Id
bndr GenStgExpr 'Vanilla
rhs
| StgLam NonEmpty (BinderP 'Vanilla)
bndrs GenStgExpr 'Vanilla
body <- GenStgExpr 'Vanilla
rhs
=
( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
dontCareCCS
UpdateFlag
ReEntrant
(NonEmpty Id -> [Id]
forall a. NonEmpty a -> [a]
toList NonEmpty Id
NonEmpty (BinderP 'Vanilla)
bndrs) GenStgExpr 'Vanilla
body
, CollectedCCs
ccs )
| StgConApp DataCon
con [StgArg]
args [Type]
_ <- GenStgExpr 'Vanilla
unticked_rhs
,
Bool -> Bool
not (DynFlags -> Module -> DataCon -> [StgArg] -> Bool
isDllConApp DynFlags
dflags Module
this_mod DataCon
con [StgArg]
args)
=
ASSERT2( not (isUnboxedTupleCon con || isUnboxedSumCon con)
, ppr bndr $$ ppr con $$ ppr args)
( CostCentreStack -> DataCon -> [StgArg] -> StgRhs
forall (pass :: StgPass).
CostCentreStack -> DataCon -> [StgArg] -> GenStgRhs pass
StgRhsCon CostCentreStack
dontCareCCS DataCon
con [StgArg]
args, CollectedCCs
ccs )
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_AutoSccsOnIndividualCafs DynFlags
dflags
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
caf_ccs
UpdateFlag
upd_flag [] GenStgExpr 'Vanilla
rhs
, CostCentre -> CostCentreStack -> CollectedCCs -> CollectedCCs
collectCC CostCentre
caf_cc CostCentreStack
caf_ccs CollectedCCs
ccs )
| Bool
otherwise
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
all_cafs_ccs
UpdateFlag
upd_flag [] GenStgExpr 'Vanilla
rhs
, CollectedCCs
ccs )
where
unticked_rhs :: GenStgExpr 'Vanilla
unticked_rhs = (Tickish Id -> Bool) -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (p :: StgPass).
(Tickish Id -> Bool) -> GenStgExpr p -> GenStgExpr p
stripStgTicksTopE (Bool -> Bool
not (Bool -> Bool) -> (Tickish Id -> Bool) -> Tickish Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode) GenStgExpr 'Vanilla
rhs
upd_flag :: UpdateFlag
upd_flag | JointDmd (Str StrDmd) (Use UseDmd) -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isUsedOnce (Id -> JointDmd (Str StrDmd) (Use UseDmd)
idDemandInfo Id
bndr) = UpdateFlag
SingleEntry
| Bool
otherwise = UpdateFlag
Updatable
caf_cc :: CostCentre
caf_cc = Id -> Module -> CostCentre
mkAutoCC Id
bndr Module
modl
caf_ccs :: CostCentreStack
caf_ccs = CostCentre -> CostCentreStack
mkSingletonCCS CostCentre
caf_cc
modl :: Module
modl | Just Module
m <- Name -> Maybe Module
nameModule_maybe (Id -> Name
idName Id
bndr) = Module
m
| Bool
otherwise = Module
this_mod
(CostCentre
_, CostCentreStack
all_cafs_ccs) = Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod
mkStgRhs :: Id -> StgExpr -> StgRhs
mkStgRhs :: Id -> GenStgExpr 'Vanilla -> StgRhs
mkStgRhs Id
bndr GenStgExpr 'Vanilla
rhs
| StgLam NonEmpty (BinderP 'Vanilla)
bndrs GenStgExpr 'Vanilla
body <- GenStgExpr 'Vanilla
rhs
= XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
ReEntrant
(NonEmpty Id -> [Id]
forall a. NonEmpty a -> [a]
toList NonEmpty Id
NonEmpty (BinderP 'Vanilla)
bndrs) GenStgExpr 'Vanilla
body
| Id -> Bool
isJoinId Id
bndr
= ASSERT(idJoinArity bndr == 0)
XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
ReEntrant
[] GenStgExpr 'Vanilla
rhs
| StgConApp DataCon
con [StgArg]
args [Type]
_ <- GenStgExpr 'Vanilla
unticked_rhs
= CostCentreStack -> DataCon -> [StgArg] -> StgRhs
forall (pass :: StgPass).
CostCentreStack -> DataCon -> [StgArg] -> GenStgRhs pass
StgRhsCon CostCentreStack
currentCCS DataCon
con [StgArg]
args
| Bool
otherwise
= XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> GenStgExpr 'Vanilla
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
upd_flag [] GenStgExpr 'Vanilla
rhs
where
unticked_rhs :: GenStgExpr 'Vanilla
unticked_rhs = (Tickish Id -> Bool) -> GenStgExpr 'Vanilla -> GenStgExpr 'Vanilla
forall (p :: StgPass).
(Tickish Id -> Bool) -> GenStgExpr p -> GenStgExpr p
stripStgTicksTopE (Bool -> Bool
not (Bool -> Bool) -> (Tickish Id -> Bool) -> Tickish Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishIsCode) GenStgExpr 'Vanilla
rhs
upd_flag :: UpdateFlag
upd_flag | JointDmd (Str StrDmd) (Use UseDmd) -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isUsedOnce (Id -> JointDmd (Str StrDmd) (Use UseDmd)
idDemandInfo Id
bndr) = UpdateFlag
SingleEntry
| Bool
otherwise = UpdateFlag
Updatable
newtype CtsM a = CtsM
{ CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM :: DynFlags
-> IdEnv HowBound
-> a
}
deriving (a -> CtsM b -> CtsM a
(a -> b) -> CtsM a -> CtsM b
(forall a b. (a -> b) -> CtsM a -> CtsM b)
-> (forall a b. a -> CtsM b -> CtsM a) -> Functor CtsM
forall a b. a -> CtsM b -> CtsM a
forall a b. (a -> b) -> CtsM a -> CtsM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> CtsM b -> CtsM a
$c<$ :: forall a b. a -> CtsM b -> CtsM a
fmap :: (a -> b) -> CtsM a -> CtsM b
$cfmap :: forall a b. (a -> b) -> CtsM a -> CtsM b
Functor)
data HowBound
= ImportBound
| LetBound
LetInfo
Arity
| LambdaBound
deriving (HowBound -> HowBound -> Bool
(HowBound -> HowBound -> Bool)
-> (HowBound -> HowBound -> Bool) -> Eq HowBound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HowBound -> HowBound -> Bool
$c/= :: HowBound -> HowBound -> Bool
== :: HowBound -> HowBound -> Bool
$c== :: HowBound -> HowBound -> Bool
External instance of the constraint type Eq JoinArity
Instance of class: Eq of the constraint type Eq LetInfo
Eq)
data LetInfo
= TopLet
| NestedLet
deriving (LetInfo -> LetInfo -> Bool
(LetInfo -> LetInfo -> Bool)
-> (LetInfo -> LetInfo -> Bool) -> Eq LetInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LetInfo -> LetInfo -> Bool
$c/= :: LetInfo -> LetInfo -> Bool
== :: LetInfo -> LetInfo -> Bool
$c== :: LetInfo -> LetInfo -> Bool
Eq)
initCts :: DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts :: DynFlags -> IdEnv HowBound -> CtsM a -> a
initCts DynFlags
dflags IdEnv HowBound
env CtsM a
m = CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
m DynFlags
dflags IdEnv HowBound
env
{-# INLINE thenCts #-}
{-# INLINE returnCts #-}
returnCts :: a -> CtsM a
returnCts :: a -> CtsM a
returnCts a
e = (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> a) -> CtsM a)
-> (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ IdEnv HowBound
_ -> a
e
thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
thenCts CtsM a
m a -> CtsM b
k = (DynFlags -> IdEnv HowBound -> b) -> CtsM b
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> b) -> CtsM b)
-> (DynFlags -> IdEnv HowBound -> b) -> CtsM b
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
env
-> CtsM b -> DynFlags -> IdEnv HowBound -> b
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM (a -> CtsM b
k (CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
m DynFlags
dflags IdEnv HowBound
env)) DynFlags
dflags IdEnv HowBound
env
instance Applicative CtsM where
pure :: a -> CtsM a
pure = a -> CtsM a
forall a. a -> CtsM a
returnCts
<*> :: CtsM (a -> b) -> CtsM a -> CtsM b
(<*>) = CtsM (a -> b) -> CtsM a -> CtsM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
Instance of class: Monad of the constraint type Monad CtsM
ap
instance Monad CtsM where
>>= :: CtsM a -> (a -> CtsM b) -> CtsM b
(>>=) = CtsM a -> (a -> CtsM b) -> CtsM b
forall a b. CtsM a -> (a -> CtsM b) -> CtsM b
thenCts
instance HasDynFlags CtsM where
getDynFlags :: CtsM DynFlags
getDynFlags = (DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags)
-> (DynFlags -> IdEnv HowBound -> DynFlags) -> CtsM DynFlags
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
_ -> DynFlags
dflags
extendVarEnvCts :: [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts :: [(Id, HowBound)] -> CtsM a -> CtsM a
extendVarEnvCts [(Id, HowBound)]
ids_w_howbound CtsM a
expr
= (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> a) -> CtsM a)
-> (DynFlags -> IdEnv HowBound -> a) -> CtsM a
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags IdEnv HowBound
env
-> CtsM a -> DynFlags -> IdEnv HowBound -> a
forall a. CtsM a -> DynFlags -> IdEnv HowBound -> a
unCtsM CtsM a
expr DynFlags
dflags (IdEnv HowBound -> [(Id, HowBound)] -> IdEnv HowBound
forall a. VarEnv a -> [(Id, a)] -> VarEnv a
extendVarEnvList IdEnv HowBound
env [(Id, HowBound)]
ids_w_howbound)
lookupVarCts :: Id -> CtsM HowBound
lookupVarCts :: Id -> CtsM HowBound
lookupVarCts Id
v = (DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound
forall a. (DynFlags -> IdEnv HowBound -> a) -> CtsM a
CtsM ((DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound)
-> (DynFlags -> IdEnv HowBound -> HowBound) -> CtsM HowBound
forall a b. (a -> b) -> a -> b
$ \DynFlags
_ IdEnv HowBound
env -> IdEnv HowBound -> Id -> HowBound
lookupBinding IdEnv HowBound
env Id
v
lookupBinding :: IdEnv HowBound -> Id -> HowBound
lookupBinding :: IdEnv HowBound -> Id -> HowBound
lookupBinding IdEnv HowBound
env Id
v = case IdEnv HowBound -> Id -> Maybe HowBound
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv IdEnv HowBound
env Id
v of
Just HowBound
xx -> HowBound
xx
Maybe HowBound
Nothing -> ASSERT2( isGlobalId v, ppr v ) ImportBound
getAllCAFsCC :: Module -> (CostCentre, CostCentreStack)
getAllCAFsCC :: Module -> (CostCentre, CostCentreStack)
getAllCAFsCC Module
this_mod =
let
span :: SrcSpan
span = CLabelString -> SrcSpan
mkGeneralSrcSpan (String -> CLabelString
mkFastString String
"<entire-module>")
all_cafs_cc :: CostCentre
all_cafs_cc = Module -> SrcSpan -> CostCentre
mkAllCafsCC Module
this_mod SrcSpan
span
all_cafs_ccs :: CostCentreStack
all_cafs_ccs = CostCentre -> CostCentreStack
mkSingletonCCS CostCentre
all_cafs_cc
in
(CostCentre
all_cafs_cc, CostCentreStack
all_cafs_ccs)
filterStgBinders :: [Var] -> [Var]
filterStgBinders :: [Id] -> [Id]
filterStgBinders [Id]
bndrs = (Id -> Bool) -> [Id] -> [Id]
forall a. (a -> Bool) -> [a] -> [a]
filter Id -> Bool
isId [Id]
bndrs
myCollectBinders :: Expr Var -> ([Var], Expr Var)
myCollectBinders :: CoreArg -> ([Id], CoreArg)
myCollectBinders CoreArg
expr
= [Id] -> CoreArg -> ([Id], CoreArg)
forall {a}. [a] -> Expr a -> ([a], Expr a)
go [] CoreArg
expr
where
go :: [a] -> Expr a -> ([a], Expr a)
go [a]
bs (Lam a
b Expr a
e) = [a] -> Expr a -> ([a], Expr a)
go (a
ba -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
bs) Expr a
e
go [a]
bs (Cast Expr a
e Coercion
_) = [a] -> Expr a -> ([a], Expr a)
go [a]
bs Expr a
e
go [a]
bs Expr a
e = ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
bs, Expr a
e)
myCollectArgs :: CoreExpr -> (Id, [CoreArg], [Tickish Id])
myCollectArgs :: CoreArg -> (Id, [CoreArg], [Tickish Id])
myCollectArgs CoreArg
expr
= CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go CoreArg
expr [] []
where
go :: CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go (Var Id
v) [CoreArg]
as [Tickish Id]
ts = (Id
v, [CoreArg]
as, [Tickish Id]
ts)
go (App CoreArg
f CoreArg
a) [CoreArg]
as [Tickish Id]
ts = CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go CoreArg
f (CoreArg
aCoreArg -> [CoreArg] -> [CoreArg]
forall a. a -> [a] -> [a]
:[CoreArg]
as) [Tickish Id]
ts
go (Tick Tickish Id
t CoreArg
e) [CoreArg]
as [Tickish Id]
ts = ASSERT( all isTypeArg as )
CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go CoreArg
e [CoreArg]
as (Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ts)
go (Cast CoreArg
e Coercion
_) [CoreArg]
as [Tickish Id]
ts = CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go CoreArg
e [CoreArg]
as [Tickish Id]
ts
go (Lam Id
b CoreArg
e) [CoreArg]
as [Tickish Id]
ts
| Id -> Bool
isTyVar Id
b = CoreArg
-> [CoreArg] -> [Tickish Id] -> (Id, [CoreArg], [Tickish Id])
go CoreArg
e [CoreArg]
as [Tickish Id]
ts
go CoreArg
_ [CoreArg]
_ [Tickish Id]
_ = String -> SDoc -> (Id, [CoreArg], [Tickish Id])
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"CoreToStg.myCollectArgs" (CoreArg -> SDoc
forall {a}. Outputable a => a -> SDoc
External instance of the constraint type forall b. OutputableBndr b => Outputable (Expr b)
External instance of the constraint type OutputableBndr Id
ppr CoreArg
expr)
stgArity :: Id -> HowBound -> Arity
stgArity :: Id -> HowBound -> JoinArity
stgArity Id
_ (LetBound LetInfo
_ JoinArity
arity) = JoinArity
arity
stgArity Id
f HowBound
ImportBound = Id -> JoinArity
idArity Id
f
stgArity Id
_ HowBound
LambdaBound = JoinArity
0