-- |
-- Various utilities for forcing Core structures
--
-- It can often be useful to force various parts of the AST. This module
-- provides a number of @seq@-like functions to accomplish this.

module GHC.Core.Seq (
        -- * Utilities for forcing Core structures
        seqExpr, seqExprs, seqUnfolding, seqRules,
        megaSeqIdInfo, seqRuleInfo, seqBinds,
    ) where

import GHC.Prelude

import GHC.Core
import GHC.Types.Id.Info
import GHC.Types.Demand( seqDemand, seqStrictSig )
import GHC.Types.Cpr( seqCprSig )
import GHC.Types.Basic( seqOccInfo )
import GHC.Types.Var.Set( seqDVarSet )
import GHC.Types.Var( varType, tyVarKind )
import GHC.Core.Type( seqType, isTyVar )
import GHC.Core.Coercion( seqCo )
import GHC.Types.Id( Id, idInfo )

-- | Evaluate all the fields of the 'IdInfo' that are generally demanded by the
-- compiler
megaSeqIdInfo :: IdInfo -> ()
megaSeqIdInfo :: IdInfo -> ()
megaSeqIdInfo IdInfo
info
  = RuleInfo -> ()
seqRuleInfo (IdInfo -> RuleInfo
ruleInfo IdInfo
info)                 () -> () -> ()
`seq`

-- Omitting this improves runtimes a little, presumably because
-- some unfoldings are not calculated at all
--    seqUnfolding (unfoldingInfo info)         `seq`

    Demand -> ()
seqDemand (IdInfo -> Demand
demandInfo IdInfo
info)                 () -> () -> ()
`seq`
    StrictSig -> ()
seqStrictSig (IdInfo -> StrictSig
strictnessInfo IdInfo
info)          () -> () -> ()
`seq`
    CprSig -> ()
seqCprSig (IdInfo -> CprSig
cprInfo IdInfo
info)                    () -> () -> ()
`seq`
    CafInfo -> ()
seqCaf (IdInfo -> CafInfo
cafInfo IdInfo
info)                       () -> () -> ()
`seq`
    OneShotInfo -> ()
seqOneShot (IdInfo -> OneShotInfo
oneShotInfo IdInfo
info)               () -> () -> ()
`seq`
    OccInfo -> ()
seqOccInfo (IdInfo -> OccInfo
occInfo IdInfo
info)

seqOneShot :: OneShotInfo -> ()
seqOneShot :: OneShotInfo -> ()
seqOneShot OneShotInfo
l = OneShotInfo
l OneShotInfo -> () -> ()
`seq` ()

seqRuleInfo :: RuleInfo -> ()
seqRuleInfo :: RuleInfo -> ()
seqRuleInfo (RuleInfo [CoreRule]
rules DVarSet
fvs) = [CoreRule] -> ()
seqRules [CoreRule]
rules () -> () -> ()
`seq` DVarSet -> ()
seqDVarSet DVarSet
fvs

seqCaf :: CafInfo -> ()
seqCaf :: CafInfo -> ()
seqCaf CafInfo
c = CafInfo
c CafInfo -> () -> ()
`seq` ()

seqRules :: [CoreRule] -> ()
seqRules :: [CoreRule] -> ()
seqRules [] = ()
seqRules (Rule { ru_bndrs :: CoreRule -> [CoreBndr]
ru_bndrs = [CoreBndr]
bndrs, ru_args :: CoreRule -> [CoreExpr]
ru_args = [CoreExpr]
args, ru_rhs :: CoreRule -> CoreExpr
ru_rhs = CoreExpr
rhs } : [CoreRule]
rules)
  = [CoreBndr] -> ()
seqBndrs [CoreBndr]
bndrs () -> () -> ()
`seq` [CoreExpr] -> ()
seqExprs (CoreExpr
rhsCoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
:[CoreExpr]
args) () -> () -> ()
`seq` [CoreRule] -> ()
seqRules [CoreRule]
rules
seqRules (BuiltinRule {} : [CoreRule]
rules) = [CoreRule] -> ()
seqRules [CoreRule]
rules

seqExpr :: CoreExpr -> ()
seqExpr :: CoreExpr -> ()
seqExpr (Var CoreBndr
v)         = CoreBndr
v CoreBndr -> () -> ()
`seq` ()
seqExpr (Lit Literal
lit)       = Literal
lit Literal -> () -> ()
`seq` ()
seqExpr (App CoreExpr
f CoreExpr
a)       = CoreExpr -> ()
seqExpr CoreExpr
f () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
a
seqExpr (Lam CoreBndr
b CoreExpr
e)       = CoreBndr -> ()
seqBndr CoreBndr
b () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e
seqExpr (Let Bind CoreBndr
b CoreExpr
e)       = Bind CoreBndr -> ()
seqBind Bind CoreBndr
b () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e
seqExpr (Case CoreExpr
e CoreBndr
b Type
t [Alt CoreBndr]
as) = CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` CoreBndr -> ()
seqBndr CoreBndr
b () -> () -> ()
`seq` Type -> ()
seqType Type
t () -> () -> ()
`seq` [Alt CoreBndr] -> ()
seqAlts [Alt CoreBndr]
as
seqExpr (Cast CoreExpr
e CoercionR
co)     = CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` CoercionR -> ()
seqCo CoercionR
co
seqExpr (Tick Tickish CoreBndr
n CoreExpr
e)      = Tickish CoreBndr -> ()
seqTickish Tickish CoreBndr
n () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e
seqExpr (Type Type
t)        = Type -> ()
seqType Type
t
seqExpr (Coercion CoercionR
co)   = CoercionR -> ()
seqCo CoercionR
co

seqExprs :: [CoreExpr] -> ()
seqExprs :: [CoreExpr] -> ()
seqExprs [] = ()
seqExprs (CoreExpr
e:[CoreExpr]
es) = CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` [CoreExpr] -> ()
seqExprs [CoreExpr]
es

seqTickish :: Tickish Id -> ()
seqTickish :: Tickish CoreBndr -> ()
seqTickish ProfNote{ profNoteCC :: forall id. Tickish id -> CostCentre
profNoteCC = CostCentre
cc } = CostCentre
cc CostCentre -> () -> ()
`seq` ()
seqTickish HpcTick{} = ()
seqTickish Breakpoint{ breakpointFVs :: forall id. Tickish id -> [id]
breakpointFVs = [CoreBndr]
ids } = [CoreBndr] -> ()
seqBndrs [CoreBndr]
ids
seqTickish SourceNote{} = ()

seqBndr :: CoreBndr -> ()
seqBndr :: CoreBndr -> ()
seqBndr CoreBndr
b | CoreBndr -> Bool
isTyVar CoreBndr
b = Type -> ()
seqType (CoreBndr -> Type
tyVarKind CoreBndr
b)
          | Bool
otherwise = Type -> ()
seqType (CoreBndr -> Type
varType CoreBndr
b)             () -> () -> ()
`seq`
                        IdInfo -> ()
megaSeqIdInfo (HasDebugCallStack => CoreBndr -> IdInfo
CoreBndr -> IdInfo
idInfo CoreBndr
b)

seqBndrs :: [CoreBndr] -> ()
seqBndrs :: [CoreBndr] -> ()
seqBndrs [] = ()
seqBndrs (CoreBndr
b:[CoreBndr]
bs) = CoreBndr -> ()
seqBndr CoreBndr
b () -> () -> ()
`seq` [CoreBndr] -> ()
seqBndrs [CoreBndr]
bs

seqBinds :: [Bind CoreBndr] -> ()
seqBinds :: [Bind CoreBndr] -> ()
seqBinds [Bind CoreBndr]
bs = (Bind CoreBndr -> () -> ()) -> () -> [Bind CoreBndr] -> ()
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (() -> () -> ()
seq (() -> () -> ())
-> (Bind CoreBndr -> ()) -> Bind CoreBndr -> () -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bind CoreBndr -> ()
seqBind) () [Bind CoreBndr]
bs

seqBind :: Bind CoreBndr -> ()
seqBind :: Bind CoreBndr -> ()
seqBind (NonRec CoreBndr
b CoreExpr
e) = CoreBndr -> ()
seqBndr CoreBndr
b () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e
seqBind (Rec [(CoreBndr, CoreExpr)]
prs)    = [(CoreBndr, CoreExpr)] -> ()
seqPairs [(CoreBndr, CoreExpr)]
prs

seqPairs :: [(CoreBndr, CoreExpr)] -> ()
seqPairs :: [(CoreBndr, CoreExpr)] -> ()
seqPairs [] = ()
seqPairs ((CoreBndr
b,CoreExpr
e):[(CoreBndr, CoreExpr)]
prs) = CoreBndr -> ()
seqBndr CoreBndr
b () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` [(CoreBndr, CoreExpr)] -> ()
seqPairs [(CoreBndr, CoreExpr)]
prs

seqAlts :: [CoreAlt] -> ()
seqAlts :: [Alt CoreBndr] -> ()
seqAlts [] = ()
seqAlts ((AltCon
c,[CoreBndr]
bs,CoreExpr
e):[Alt CoreBndr]
alts) = AltCon
c AltCon -> () -> ()
`seq` [CoreBndr] -> ()
seqBndrs [CoreBndr]
bs () -> () -> ()
`seq` CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` [Alt CoreBndr] -> ()
seqAlts [Alt CoreBndr]
alts

seqUnfolding :: Unfolding -> ()
seqUnfolding :: Unfolding -> ()
seqUnfolding (CoreUnfolding { uf_tmpl :: Unfolding -> CoreExpr
uf_tmpl = CoreExpr
e, uf_is_top :: Unfolding -> Bool
uf_is_top = Bool
top,
                uf_is_value :: Unfolding -> Bool
uf_is_value = Bool
b1, uf_is_work_free :: Unfolding -> Bool
uf_is_work_free = Bool
b2,
                uf_expandable :: Unfolding -> Bool
uf_expandable = Bool
b3, uf_is_conlike :: Unfolding -> Bool
uf_is_conlike = Bool
b4,
                uf_guidance :: Unfolding -> UnfoldingGuidance
uf_guidance = UnfoldingGuidance
g})
  = CoreExpr -> ()
seqExpr CoreExpr
e () -> () -> ()
`seq` Bool
top Bool -> () -> ()
`seq` Bool
b1 Bool -> () -> ()
`seq` Bool
b2 Bool -> () -> ()
`seq` Bool
b3 Bool -> () -> ()
`seq` Bool
b4 Bool -> () -> ()
`seq` UnfoldingGuidance -> ()
seqGuidance UnfoldingGuidance
g

seqUnfolding Unfolding
_ = ()

seqGuidance :: UnfoldingGuidance -> ()
seqGuidance :: UnfoldingGuidance -> ()
seqGuidance (UnfIfGoodArgs [Int]
ns Int
n Int
b) = Int
n Int -> () -> ()
`seq` [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
ns Int -> () -> ()
`seq` Int
b Int -> () -> ()
`seq` ()
seqGuidance UnfoldingGuidance
_                      = ()