module GHC.Stg.Make
( MkStgRhs (..)
, mkTopStgRhs
, mkStgRhs
, mkStgRhsCon_maybe
, mkTopStgRhsCon_maybe
)
where
import GHC.Prelude
import GHC.Unit.Module
import GHC.Core.DataCon
import GHC.Core.Type (Type)
import GHC.Stg.Syntax
import GHC.Stg.Utils (stripStgTicksTop)
import GHC.Types.Id
import GHC.Types.Name
import GHC.Types.CostCentre
import GHC.Types.Demand ( isAtMostOnceDmd )
import GHC.Types.Tickish
data MkStgRhs = MkStgRhs
{ MkStgRhs -> [Id]
rhs_args :: [Id]
, MkStgRhs -> StgExpr
rhs_expr :: StgExpr
, MkStgRhs -> Type
rhs_type :: Type
, MkStgRhs -> Bool
rhs_is_join :: !Bool
}
mkTopStgRhs :: (Module -> DataCon -> [StgArg] -> Bool)
-> Bool -> Module -> CollectedCCs
-> Id -> MkStgRhs -> (StgRhs, CollectedCCs)
mkTopStgRhs :: (Module -> DataCon -> [StgArg] -> Bool)
-> Bool
-> Module
-> CollectedCCs
-> Id
-> MkStgRhs
-> (StgRhs, CollectedCCs)
mkTopStgRhs Module -> DataCon -> [StgArg] -> Bool
allow_toplevel_con_app Bool
opt_AutoSccsOnIndividualCafs Module
this_mod CollectedCCs
ccs Id
bndr mk_rhs :: MkStgRhs
mk_rhs@(MkStgRhs [Id]
bndrs StgExpr
rhs Type
typ Bool
_)
| Just StgRhs
rhs_con <- (DataCon -> [StgArg] -> Bool) -> MkStgRhs -> Maybe StgRhs
mkTopStgRhsCon_maybe (Module -> DataCon -> [StgArg] -> Bool
allow_toplevel_con_app Module
this_mod) MkStgRhs
mk_rhs
= ( StgRhs
rhs_con, CollectedCCs
ccs )
| Bool -> Bool
not ([Id] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
bndrs)
=
( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> Type
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> Type
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
dontCareCCS
UpdateFlag
ReEntrant
[Id]
[BinderP 'Vanilla]
bndrs StgExpr
rhs Type
typ
, CollectedCCs
ccs )
| Bool
opt_AutoSccsOnIndividualCafs
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> Type
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> Type
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
caf_ccs
UpdateFlag
upd_flag [] StgExpr
rhs Type
typ
, CostCentre -> CostCentreStack -> CollectedCCs -> CollectedCCs
collectCC CostCentre
caf_cc CostCentreStack
caf_ccs CollectedCCs
ccs )
| Bool
otherwise
= ( XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> Type
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> Type
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
all_cafs_ccs
UpdateFlag
upd_flag [] StgExpr
rhs Type
typ
, CollectedCCs
ccs )
where
upd_flag :: UpdateFlag
upd_flag | Demand -> Bool
isAtMostOnceDmd (Id -> Demand
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 -> MkStgRhs -> StgRhs
mkStgRhs :: Id -> MkStgRhs -> StgRhs
mkStgRhs Id
bndr mk_rhs :: MkStgRhs
mk_rhs@(MkStgRhs [Id]
bndrs StgExpr
rhs Type
typ Bool
is_join)
| Just StgRhs
rhs_con <- MkStgRhs -> Maybe StgRhs
mkStgRhsCon_maybe MkStgRhs
mk_rhs
= StgRhs
rhs_con
| Bool
otherwise
= XRhsClosure 'Vanilla
-> CostCentreStack
-> UpdateFlag
-> [BinderP 'Vanilla]
-> StgExpr
-> Type
-> StgRhs
forall (pass :: StgPass).
XRhsClosure pass
-> CostCentreStack
-> UpdateFlag
-> [BinderP pass]
-> GenStgExpr pass
-> Type
-> GenStgRhs pass
StgRhsClosure XRhsClosure 'Vanilla
NoExtFieldSilent
noExtFieldSilent
CostCentreStack
currentCCS
UpdateFlag
upd_flag [Id]
[BinderP 'Vanilla]
bndrs StgExpr
rhs Type
typ
where
upd_flag :: UpdateFlag
upd_flag | Bool
is_join = UpdateFlag
JumpedTo
| Bool -> Bool
not ([Id] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
bndrs) = UpdateFlag
ReEntrant
| Demand -> Bool
isAtMostOnceDmd (Id -> Demand
idDemandInfo Id
bndr) = UpdateFlag
SingleEntry
| Bool
otherwise = UpdateFlag
Updatable
mkStgRhsCon_maybe :: MkStgRhs -> Maybe StgRhs
mkStgRhsCon_maybe :: MkStgRhs -> Maybe StgRhs
mkStgRhsCon_maybe (MkStgRhs [Id]
bndrs StgExpr
rhs Type
typ Bool
is_join)
| [] <- [Id]
bndrs
, Bool -> Bool
not Bool
is_join
, ([StgTickish]
ticks, StgConApp DataCon
con ConstructorNumber
mn [StgArg]
args [[PrimRep]]
_) <- (StgTickish -> Bool) -> StgExpr -> ([StgTickish], StgExpr)
forall (p :: StgPass).
(StgTickish -> Bool)
-> GenStgExpr p -> ([StgTickish], GenStgExpr p)
stripStgTicksTop (Bool -> Bool
not (Bool -> Bool) -> (StgTickish -> Bool) -> StgTickish -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishIsCode) StgExpr
rhs
= StgRhs -> Maybe StgRhs
forall a. a -> Maybe a
Just (CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> StgRhs
forall (pass :: StgPass).
CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> GenStgRhs pass
StgRhsCon CostCentreStack
currentCCS DataCon
con ConstructorNumber
mn [StgTickish]
ticks [StgArg]
args Type
typ)
| Bool
otherwise = Maybe StgRhs
forall a. Maybe a
Nothing
mkTopStgRhsCon_maybe :: (DataCon -> [StgArg] -> Bool) -> MkStgRhs -> Maybe StgRhs
mkTopStgRhsCon_maybe :: (DataCon -> [StgArg] -> Bool) -> MkStgRhs -> Maybe StgRhs
mkTopStgRhsCon_maybe DataCon -> [StgArg] -> Bool
allow_static_con_app (MkStgRhs [Id]
bndrs StgExpr
rhs Type
typ Bool
is_join)
| [] <- [Id]
bndrs
, Bool -> Bool
not Bool
is_join
, ([StgTickish]
ticks, StgConApp DataCon
con ConstructorNumber
mn [StgArg]
args [[PrimRep]]
_) <- (StgTickish -> Bool) -> StgExpr -> ([StgTickish], StgExpr)
forall (p :: StgPass).
(StgTickish -> Bool)
-> GenStgExpr p -> ([StgTickish], GenStgExpr p)
stripStgTicksTop (Bool -> Bool
not (Bool -> Bool) -> (StgTickish -> Bool) -> StgTickish -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishIsCode) StgExpr
rhs
, DataCon -> [StgArg] -> Bool
allow_static_con_app DataCon
con [StgArg]
args
= StgRhs -> Maybe StgRhs
forall a. a -> Maybe a
Just (CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> StgRhs
forall (pass :: StgPass).
CostCentreStack
-> DataCon
-> ConstructorNumber
-> [StgTickish]
-> [StgArg]
-> Type
-> GenStgRhs pass
StgRhsCon CostCentreStack
dontCareCCS DataCon
con ConstructorNumber
mn [StgTickish]
ticks [StgArg]
args Type
typ)
| Bool
otherwise = Maybe StgRhs
forall a. Maybe a
Nothing