{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.Core.Opt.CSE (cseProgram, cseOneExpr) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Core.Subst
import GHC.Types.Var ( Var )
import GHC.Types.Var.Env ( mkInScopeSet )
import GHC.Types.Id ( Id, idType, idHasRules, zapStableUnfolding
, idInlineActivation, setInlineActivation
, zapIdOccInfo, zapIdUsageInfo, idInlinePragma
, isJoinId, isJoinId_maybe )
import GHC.Core.Utils ( mkAltExpr, eqExpr
, exprIsTickedString
, stripTicksE, stripTicksT, mkTicks )
import GHC.Core.FVs ( exprFreeVars )
import GHC.Core.Type ( tyConAppArgs )
import GHC.Core
import GHC.Utils.Outputable
import GHC.Types.Basic
import GHC.Types.Tickish
import GHC.Core.Map.Expr
import GHC.Utils.Misc ( filterOut, equalLength, debugIsOn )
import GHC.Utils.Panic
import Data.List ( mapAccumL )
cseProgram :: CoreProgram -> CoreProgram
cseProgram :: CoreProgram -> CoreProgram
cseProgram CoreProgram
binds = (CSEnv, CoreProgram) -> CoreProgram
forall a b. (a, b) -> b
snd ((CSEnv -> CoreBind -> (CSEnv, CoreBind))
-> CSEnv -> CoreProgram -> (CSEnv, CoreProgram)
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL (TopLevelFlag -> CSEnv -> CoreBind -> (CSEnv, CoreBind)
cseBind TopLevelFlag
TopLevel) CSEnv
emptyCSEnv CoreProgram
binds)
cseBind :: TopLevelFlag -> CSEnv -> CoreBind -> (CSEnv, CoreBind)
cseBind :: TopLevelFlag -> CSEnv -> CoreBind -> (CSEnv, CoreBind)
cseBind TopLevelFlag
toplevel CSEnv
env (NonRec Var
b Expr Var
e)
= (CSEnv
env2, Var -> Expr Var -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Var
b2 Expr Var
e2)
where
(CSEnv
env1, Var
b1) = CSEnv -> Var -> (CSEnv, Var)
addBinder CSEnv
env Var
b
(CSEnv
env2, (Var
b2, Expr Var
e2)) = TopLevelFlag
-> CSEnv -> (Var, Expr Var) -> Var -> (CSEnv, (Var, Expr Var))
cse_bind TopLevelFlag
toplevel CSEnv
env1 (Var
b,Expr Var
e) Var
b1
cseBind TopLevelFlag
toplevel CSEnv
env (Rec [(Var
in_id, Expr Var
rhs)])
| Var -> Bool
noCSE Var
in_id
= (CSEnv
env1, [(Var, Expr Var)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Var
out_id, Expr Var
rhs')])
| Just Expr Var
previous <- CSEnv -> Var -> Expr Var -> Maybe (Expr Var)
lookupCSRecEnv CSEnv
env Var
out_id Expr Var
rhs''
, let previous' :: Expr Var
previous' = [CoreTickish] -> Expr Var -> Expr Var
mkTicks [CoreTickish]
ticks Expr Var
previous
out_id' :: Var
out_id' = TopLevelFlag -> Var -> Var
delayInlining TopLevelFlag
toplevel Var
out_id
=
(CSEnv -> Var -> Expr Var -> CSEnv
extendCSSubst CSEnv
env1 Var
in_id Expr Var
previous', Var -> Expr Var -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Var
out_id' Expr Var
previous')
| Bool
otherwise
= (CSEnv -> Var -> Expr Var -> Expr Var -> CSEnv
extendCSRecEnv CSEnv
env1 Var
out_id Expr Var
rhs'' Expr Var
id_expr', [(Var, Expr Var)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Var
zapped_id, Expr Var
rhs')])
where
(CSEnv
env1, [Var
out_id]) = CSEnv -> [Var] -> (CSEnv, [Var])
addRecBinders CSEnv
env [Var
in_id]
rhs' :: Expr Var
rhs' = CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env1 Expr Var
rhs
rhs'' :: Expr Var
rhs'' = (CoreTickish -> Bool) -> Expr Var -> Expr Var
forall b. (CoreTickish -> Bool) -> Expr b -> Expr b
stripTicksE CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Var
rhs'
ticks :: [CoreTickish]
ticks = (CoreTickish -> Bool) -> Expr Var -> [CoreTickish]
forall b. (CoreTickish -> Bool) -> Expr b -> [CoreTickish]
stripTicksT CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Var
rhs'
id_expr' :: Expr Var
id_expr' = Var -> Expr Var
forall b. Var -> Expr b
varToCoreExpr Var
out_id
zapped_id :: Var
zapped_id = Var -> Var
zapIdUsageInfo Var
out_id
cseBind TopLevelFlag
toplevel CSEnv
env (Rec [(Var, Expr Var)]
pairs)
= (CSEnv
env2, [(Var, Expr Var)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Var, Expr Var)]
pairs')
where
(CSEnv
env1, [Var]
bndrs1) = CSEnv -> [Var] -> (CSEnv, [Var])
addRecBinders CSEnv
env (((Var, Expr Var) -> Var) -> [(Var, Expr Var)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, Expr Var) -> Var
forall a b. (a, b) -> a
fst [(Var, Expr Var)]
pairs)
(CSEnv
env2, [(Var, Expr Var)]
pairs') = (CSEnv -> ((Var, Expr Var), Var) -> (CSEnv, (Var, Expr Var)))
-> CSEnv -> [((Var, Expr Var), Var)] -> (CSEnv, [(Var, Expr Var)])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL CSEnv -> ((Var, Expr Var), Var) -> (CSEnv, (Var, Expr Var))
do_one CSEnv
env1 ([(Var, Expr Var)] -> [Var] -> [((Var, Expr Var), Var)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Var, Expr Var)]
pairs [Var]
bndrs1)
do_one :: CSEnv -> ((Var, Expr Var), Var) -> (CSEnv, (Var, Expr Var))
do_one CSEnv
env ((Var, Expr Var)
pr, Var
b1) = TopLevelFlag
-> CSEnv -> (Var, Expr Var) -> Var -> (CSEnv, (Var, Expr Var))
cse_bind TopLevelFlag
toplevel CSEnv
env (Var, Expr Var)
pr Var
b1
cse_bind :: TopLevelFlag -> CSEnv -> (InId, InExpr) -> OutId -> (CSEnv, (OutId, OutExpr))
cse_bind :: TopLevelFlag
-> CSEnv -> (Var, Expr Var) -> Var -> (CSEnv, (Var, Expr Var))
cse_bind TopLevelFlag
toplevel CSEnv
env (Var
in_id, Expr Var
in_rhs) Var
out_id
| TopLevelFlag -> Bool
isTopLevel TopLevelFlag
toplevel, Expr Var -> Bool
exprIsTickedString Expr Var
in_rhs
= (CSEnv
env', (Var
out_id', Expr Var
in_rhs))
| Just JoinArity
arity <- Var -> Maybe JoinArity
isJoinId_maybe Var
in_id
= let ([Var]
params, Expr Var
in_body) = JoinArity -> Expr Var -> ([Var], Expr Var)
forall b. JoinArity -> Expr b -> ([b], Expr b)
collectNBinders JoinArity
arity Expr Var
in_rhs
(CSEnv
env', [Var]
params') = CSEnv -> [Var] -> (CSEnv, [Var])
addBinders CSEnv
env [Var]
params
out_body :: Expr Var
out_body = CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
env' Expr Var
in_body
in (CSEnv
env, (Var
out_id, [Var] -> Expr Var -> Expr Var
forall b. [b] -> Expr b -> Expr b
mkLams [Var]
params' Expr Var
out_body))
| Bool
otherwise
= (CSEnv
env', (Var
out_id'', Expr Var
out_rhs))
where
(CSEnv
env', Var
out_id') = CSEnv -> Var -> Var -> Expr Var -> Bool -> (CSEnv, Var)
addBinding CSEnv
env Var
in_id Var
out_id Expr Var
out_rhs Bool
cse_done
(Bool
cse_done, Expr Var
out_rhs) = CSEnv -> Expr Var -> (Bool, Expr Var)
try_for_cse CSEnv
env Expr Var
in_rhs
out_id'' :: Var
out_id'' | Bool
cse_done = Var -> Var
zapStableUnfolding (Var -> Var) -> Var -> Var
forall a b. (a -> b) -> a -> b
$
TopLevelFlag -> Var -> Var
delayInlining TopLevelFlag
toplevel Var
out_id'
| Bool
otherwise = Var
out_id'
delayInlining :: TopLevelFlag -> Id -> Id
delayInlining :: TopLevelFlag -> Var -> Var
delayInlining TopLevelFlag
top_lvl Var
bndr
| TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
, Activation -> Bool
isAlwaysActive (Var -> Activation
idInlineActivation Var
bndr)
, Var -> Bool
idHasRules Var
bndr
= Var
bndr Var -> Activation -> Var
`setInlineActivation` Activation
activateAfterInitial
| Bool
otherwise
= Var
bndr
addBinding :: CSEnv
-> InVar
-> OutId -> OutExpr
-> Bool
-> (CSEnv, OutId)
addBinding :: CSEnv -> Var -> Var -> Expr Var -> Bool -> (CSEnv, Var)
addBinding CSEnv
env Var
in_id Var
out_id Expr Var
rhs' Bool
cse_done
| Bool -> Bool
not (Var -> Bool
isId Var
in_id) = (CSEnv -> Var -> Expr Var -> CSEnv
extendCSSubst CSEnv
env Var
in_id Expr Var
rhs', Var
out_id)
| Var -> Bool
noCSE Var
in_id = (CSEnv
env, Var
out_id)
| Bool
use_subst = (CSEnv -> Var -> Expr Var -> CSEnv
extendCSSubst CSEnv
env Var
in_id Expr Var
rhs', Var
out_id)
| Bool
cse_done = (CSEnv
env, Var
out_id)
| Bool
otherwise = (CSEnv -> Expr Var -> Expr Var -> CSEnv
extendCSEnv CSEnv
env Expr Var
rhs' Expr Var
id_expr', Var
zapped_id)
where
id_expr' :: Expr Var
id_expr' = Var -> Expr Var
forall b. Var -> Expr b
varToCoreExpr Var
out_id
zapped_id :: Var
zapped_id = Var -> Var
zapIdUsageInfo Var
out_id
use_subst :: Bool
use_subst | Var {} <- Expr Var
rhs' = Bool
True
| Bool
otherwise = Bool
False
noCSE :: InId -> Bool
noCSE :: Var -> Bool
noCSE Var
id = Bool -> Bool
not (Activation -> Bool
isAlwaysActive (Var -> Activation
idInlineActivation Var
id)) Bool -> Bool -> Bool
&&
Bool -> Bool
not (InlineSpec -> Bool
noUserInlineSpec (InlinePragma -> InlineSpec
inlinePragmaSpec (Var -> InlinePragma
idInlinePragma Var
id)))
Bool -> Bool -> Bool
|| InlinePragma -> Bool
isAnyInlinePragma (Var -> InlinePragma
idInlinePragma Var
id)
Bool -> Bool -> Bool
|| Var -> Bool
isJoinId Var
id
tryForCSE :: CSEnv -> InExpr -> OutExpr
tryForCSE :: CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
env Expr Var
expr = (Bool, Expr Var) -> Expr Var
forall a b. (a, b) -> b
snd (CSEnv -> Expr Var -> (Bool, Expr Var)
try_for_cse CSEnv
env Expr Var
expr)
try_for_cse :: CSEnv -> InExpr -> (Bool, OutExpr)
try_for_cse :: CSEnv -> Expr Var -> (Bool, Expr Var)
try_for_cse CSEnv
env Expr Var
expr
| Just Expr Var
e <- CSEnv -> Expr Var -> Maybe (Expr Var)
lookupCSEnv CSEnv
env Expr Var
expr'' = (Bool
True, [CoreTickish] -> Expr Var -> Expr Var
mkTicks [CoreTickish]
ticks Expr Var
e)
| Bool
otherwise = (Bool
False, Expr Var
expr')
where
expr' :: Expr Var
expr' = CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env Expr Var
expr
expr'' :: Expr Var
expr'' = (CoreTickish -> Bool) -> Expr Var -> Expr Var
forall b. (CoreTickish -> Bool) -> Expr b -> Expr b
stripTicksE CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Var
expr'
ticks :: [CoreTickish]
ticks = (CoreTickish -> Bool) -> Expr Var -> [CoreTickish]
forall b. (CoreTickish -> Bool) -> Expr b -> [CoreTickish]
stripTicksT CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Var
expr'
cseOneExpr :: InExpr -> OutExpr
cseOneExpr :: Expr Var -> Expr Var
cseOneExpr Expr Var
e = CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env Expr Var
e
where env :: CSEnv
env = CSEnv
emptyCSEnv {cs_subst :: Subst
cs_subst = InScopeSet -> Subst
mkEmptySubst (VarSet -> InScopeSet
mkInScopeSet (Expr Var -> VarSet
exprFreeVars Expr Var
e)) }
cseExpr :: CSEnv -> InExpr -> OutExpr
cseExpr :: CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env (Type Type
t) = Type -> Expr Var
forall b. Type -> Expr b
Type (Subst -> Type -> Type
substTy (CSEnv -> Subst
csEnvSubst CSEnv
env) Type
t)
cseExpr CSEnv
env (Coercion Coercion
c) = Coercion -> Expr Var
forall b. Coercion -> Expr b
Coercion (HasCallStack => Subst -> Coercion -> Coercion
Subst -> Coercion -> Coercion
substCo (CSEnv -> Subst
csEnvSubst CSEnv
env) Coercion
c)
cseExpr CSEnv
_ (Lit Literal
lit) = Literal -> Expr Var
forall b. Literal -> Expr b
Lit Literal
lit
cseExpr CSEnv
env (Var Var
v) = CSEnv -> Var -> Expr Var
lookupSubst CSEnv
env Var
v
cseExpr CSEnv
env (App Expr Var
f Expr Var
a) = Expr Var -> Expr Var -> Expr Var
forall b. Expr b -> Expr b -> Expr b
App (CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env Expr Var
f) (CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
env Expr Var
a)
cseExpr CSEnv
env (Tick CoreTickish
t Expr Var
e) = CoreTickish -> Expr Var -> Expr Var
forall b. CoreTickish -> Expr b -> Expr b
Tick CoreTickish
t (CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env Expr Var
e)
cseExpr CSEnv
env (Cast Expr Var
e Coercion
co) = Expr Var -> Coercion -> Expr Var
forall b. Expr b -> Coercion -> Expr b
Cast (CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
env Expr Var
e) (HasCallStack => Subst -> Coercion -> Coercion
Subst -> Coercion -> Coercion
substCo (CSEnv -> Subst
csEnvSubst CSEnv
env) Coercion
co)
cseExpr CSEnv
env (Lam Var
b Expr Var
e) = let (CSEnv
env', Var
b') = CSEnv -> Var -> (CSEnv, Var)
addBinder CSEnv
env Var
b
in Var -> Expr Var -> Expr Var
forall b. b -> Expr b -> Expr b
Lam Var
b' (CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env' Expr Var
e)
cseExpr CSEnv
env (Let CoreBind
bind Expr Var
e) = let (CSEnv
env', CoreBind
bind') = TopLevelFlag -> CSEnv -> CoreBind -> (CSEnv, CoreBind)
cseBind TopLevelFlag
NotTopLevel CSEnv
env CoreBind
bind
in CoreBind -> Expr Var -> Expr Var
forall b. Bind b -> Expr b -> Expr b
Let CoreBind
bind' (CSEnv -> Expr Var -> Expr Var
cseExpr CSEnv
env' Expr Var
e)
cseExpr CSEnv
env (Case Expr Var
e Var
bndr Type
ty [OutAlt]
alts) = CSEnv -> Expr Var -> Var -> Type -> [OutAlt] -> Expr Var
cseCase CSEnv
env Expr Var
e Var
bndr Type
ty [OutAlt]
alts
cseCase :: CSEnv -> InExpr -> InId -> InType -> [InAlt] -> OutExpr
cseCase :: CSEnv -> Expr Var -> Var -> Type -> [OutAlt] -> Expr Var
cseCase CSEnv
env Expr Var
scrut Var
bndr Type
ty [OutAlt]
alts
= Expr Var -> Var -> Type -> [OutAlt] -> Expr Var
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case Expr Var
scrut1 Var
bndr3 Type
ty' ([OutAlt] -> Expr Var) -> [OutAlt] -> Expr Var
forall a b. (a -> b) -> a -> b
$
CSEnv -> [OutAlt] -> [OutAlt]
combineAlts CSEnv
alt_env ((OutAlt -> OutAlt) -> [OutAlt] -> [OutAlt]
forall a b. (a -> b) -> [a] -> [b]
map OutAlt -> OutAlt
cse_alt [OutAlt]
alts)
where
ty' :: Type
ty' = Subst -> Type -> Type
substTy (CSEnv -> Subst
csEnvSubst CSEnv
env) Type
ty
(Bool
cse_done, Expr Var
scrut1) = CSEnv -> Expr Var -> (Bool, Expr Var)
try_for_cse CSEnv
env Expr Var
scrut
bndr1 :: Var
bndr1 = Var -> Var
zapIdOccInfo Var
bndr
(CSEnv
env1, Var
bndr2) = CSEnv -> Var -> (CSEnv, Var)
addBinder CSEnv
env Var
bndr1
(CSEnv
alt_env, Var
bndr3) = CSEnv -> Var -> Var -> Expr Var -> Bool -> (CSEnv, Var)
addBinding CSEnv
env1 Var
bndr Var
bndr2 Expr Var
scrut1 Bool
cse_done
con_target :: OutExpr
con_target :: Expr Var
con_target = CSEnv -> Var -> Expr Var
lookupSubst CSEnv
alt_env Var
bndr
arg_tys :: [OutType]
arg_tys :: [Type]
arg_tys = Type -> [Type]
tyConAppArgs (Var -> Type
idType Var
bndr3)
cse_alt :: OutAlt -> OutAlt
cse_alt (Alt (DataAlt DataCon
con) [Var]
args Expr Var
rhs)
= AltCon -> [Var] -> Expr Var -> OutAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt (DataCon -> AltCon
DataAlt DataCon
con) [Var]
args' (CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
new_env Expr Var
rhs)
where
(CSEnv
env', [Var]
args') = CSEnv -> [Var] -> (CSEnv, [Var])
addBinders CSEnv
alt_env [Var]
args
new_env :: CSEnv
new_env = CSEnv -> Expr Var -> Expr Var -> CSEnv
extendCSEnv CSEnv
env' Expr Var
con_expr Expr Var
con_target
con_expr :: Expr Var
con_expr = AltCon -> [Var] -> [Type] -> Expr Var
mkAltExpr (DataCon -> AltCon
DataAlt DataCon
con) [Var]
args' [Type]
arg_tys
cse_alt (Alt AltCon
con [Var]
args Expr Var
rhs)
= AltCon -> [Var] -> Expr Var -> OutAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
con [Var]
args' (CSEnv -> Expr Var -> Expr Var
tryForCSE CSEnv
env' Expr Var
rhs)
where
(CSEnv
env', [Var]
args') = CSEnv -> [Var] -> (CSEnv, [Var])
addBinders CSEnv
alt_env [Var]
args
combineAlts :: CSEnv -> [OutAlt] -> [OutAlt]
combineAlts :: CSEnv -> [OutAlt] -> [OutAlt]
combineAlts CSEnv
env [OutAlt]
alts
| (Just OutAlt
alt1, [OutAlt]
rest_alts) <- [OutAlt] -> (Maybe OutAlt, [OutAlt])
find_bndr_free_alt [OutAlt]
alts
, Alt AltCon
_ [Var]
bndrs1 Expr Var
rhs1 <- OutAlt
alt1
, let filtered_alts :: [OutAlt]
filtered_alts = (OutAlt -> Bool) -> [OutAlt] -> [OutAlt]
forall a. (a -> Bool) -> [a] -> [a]
filterOut (Expr Var -> OutAlt -> Bool
identical_alt Expr Var
rhs1) [OutAlt]
rest_alts
, Bool -> Bool
not ([OutAlt] -> [OutAlt] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [OutAlt]
rest_alts [OutAlt]
filtered_alts)
= ASSERT2( null bndrs1, ppr alts )
AltCon -> [Var] -> Expr Var -> OutAlt
forall b. AltCon -> [b] -> Expr b -> Alt b
Alt AltCon
DEFAULT [] Expr Var
rhs1 OutAlt -> [OutAlt] -> [OutAlt]
forall a. a -> [a] -> [a]
: [OutAlt]
filtered_alts
| Bool
otherwise
= [OutAlt]
alts
where
in_scope :: InScopeSet
in_scope = Subst -> InScopeSet
substInScope (CSEnv -> Subst
csEnvSubst CSEnv
env)
find_bndr_free_alt :: [CoreAlt] -> (Maybe CoreAlt, [CoreAlt])
find_bndr_free_alt :: [OutAlt] -> (Maybe OutAlt, [OutAlt])
find_bndr_free_alt []
= (Maybe OutAlt
forall a. Maybe a
Nothing, [])
find_bndr_free_alt (alt :: OutAlt
alt@(Alt AltCon
_ [Var]
bndrs Expr Var
_) : [OutAlt]
alts)
| [Var] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Var]
bndrs = (OutAlt -> Maybe OutAlt
forall a. a -> Maybe a
Just OutAlt
alt, [OutAlt]
alts)
| Bool
otherwise = case [OutAlt] -> (Maybe OutAlt, [OutAlt])
find_bndr_free_alt [OutAlt]
alts of
(Maybe OutAlt
mb_bf, [OutAlt]
alts) -> (Maybe OutAlt
mb_bf, OutAlt
altOutAlt -> [OutAlt] -> [OutAlt]
forall a. a -> [a] -> [a]
:[OutAlt]
alts)
identical_alt :: Expr Var -> OutAlt -> Bool
identical_alt Expr Var
rhs1 (Alt AltCon
_ [Var]
_ Expr Var
rhs) = InScopeSet -> Expr Var -> Expr Var -> Bool
eqExpr InScopeSet
in_scope Expr Var
rhs1 Expr Var
rhs
data CSEnv
= CS { CSEnv -> Subst
cs_subst :: Subst
, CSEnv -> CoreMap (Expr Var)
cs_map :: CoreMap OutExpr
, CSEnv -> CoreMap (Expr Var)
cs_rec_map :: CoreMap OutExpr
}
emptyCSEnv :: CSEnv
emptyCSEnv :: CSEnv
emptyCSEnv = CS { cs_map :: CoreMap (Expr Var)
cs_map = CoreMap (Expr Var)
forall a. CoreMap a
emptyCoreMap, cs_rec_map :: CoreMap (Expr Var)
cs_rec_map = CoreMap (Expr Var)
forall a. CoreMap a
emptyCoreMap
, cs_subst :: Subst
cs_subst = Subst
emptySubst }
lookupCSEnv :: CSEnv -> OutExpr -> Maybe OutExpr
lookupCSEnv :: CSEnv -> Expr Var -> Maybe (Expr Var)
lookupCSEnv (CS { cs_map :: CSEnv -> CoreMap (Expr Var)
cs_map = CoreMap (Expr Var)
csmap }) Expr Var
expr
= CoreMap (Expr Var) -> Expr Var -> Maybe (Expr Var)
forall a. CoreMap a -> Expr Var -> Maybe a
lookupCoreMap CoreMap (Expr Var)
csmap Expr Var
expr
extendCSEnv :: CSEnv -> OutExpr -> OutExpr -> CSEnv
extendCSEnv :: CSEnv -> Expr Var -> Expr Var -> CSEnv
extendCSEnv CSEnv
cse Expr Var
expr Expr Var
triv_expr
= CSEnv
cse { cs_map :: CoreMap (Expr Var)
cs_map = CoreMap (Expr Var) -> Expr Var -> Expr Var -> CoreMap (Expr Var)
forall a. CoreMap a -> Expr Var -> a -> CoreMap a
extendCoreMap (CSEnv -> CoreMap (Expr Var)
cs_map CSEnv
cse) Expr Var
sexpr Expr Var
triv_expr }
where
sexpr :: Expr Var
sexpr = (CoreTickish -> Bool) -> Expr Var -> Expr Var
forall b. (CoreTickish -> Bool) -> Expr b -> Expr b
stripTicksE CoreTickish -> Bool
forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable Expr Var
expr
extendCSRecEnv :: CSEnv -> OutId -> OutExpr -> OutExpr -> CSEnv
extendCSRecEnv :: CSEnv -> Var -> Expr Var -> Expr Var -> CSEnv
extendCSRecEnv CSEnv
cse Var
bndr Expr Var
expr Expr Var
triv_expr
= CSEnv
cse { cs_rec_map :: CoreMap (Expr Var)
cs_rec_map = CoreMap (Expr Var) -> Expr Var -> Expr Var -> CoreMap (Expr Var)
forall a. CoreMap a -> Expr Var -> a -> CoreMap a
extendCoreMap (CSEnv -> CoreMap (Expr Var)
cs_rec_map CSEnv
cse) (Var -> Expr Var -> Expr Var
forall b. b -> Expr b -> Expr b
Lam Var
bndr Expr Var
expr) Expr Var
triv_expr }
lookupCSRecEnv :: CSEnv -> OutId -> OutExpr -> Maybe OutExpr
lookupCSRecEnv :: CSEnv -> Var -> Expr Var -> Maybe (Expr Var)
lookupCSRecEnv (CS { cs_rec_map :: CSEnv -> CoreMap (Expr Var)
cs_rec_map = CoreMap (Expr Var)
csmap }) Var
bndr Expr Var
expr
= CoreMap (Expr Var) -> Expr Var -> Maybe (Expr Var)
forall a. CoreMap a -> Expr Var -> Maybe a
lookupCoreMap CoreMap (Expr Var)
csmap (Var -> Expr Var -> Expr Var
forall b. b -> Expr b -> Expr b
Lam Var
bndr Expr Var
expr)
csEnvSubst :: CSEnv -> Subst
csEnvSubst :: CSEnv -> Subst
csEnvSubst = CSEnv -> Subst
cs_subst
lookupSubst :: CSEnv -> Id -> OutExpr
lookupSubst :: CSEnv -> Var -> Expr Var
lookupSubst (CS { cs_subst :: CSEnv -> Subst
cs_subst = Subst
sub}) Var
x = HasDebugCallStack => Subst -> Var -> Expr Var
Subst -> Var -> Expr Var
lookupIdSubst Subst
sub Var
x
extendCSSubst :: CSEnv -> Id -> CoreExpr -> CSEnv
extendCSSubst :: CSEnv -> Var -> Expr Var -> CSEnv
extendCSSubst CSEnv
cse Var
x Expr Var
rhs = CSEnv
cse { cs_subst :: Subst
cs_subst = Subst -> Var -> Expr Var -> Subst
extendSubst (CSEnv -> Subst
cs_subst CSEnv
cse) Var
x Expr Var
rhs }
addBinder :: CSEnv -> Var -> (CSEnv, Var)
addBinder :: CSEnv -> Var -> (CSEnv, Var)
addBinder CSEnv
cse Var
v = (CSEnv
cse { cs_subst :: Subst
cs_subst = Subst
sub' }, Var
v')
where
(Subst
sub', Var
v') = Subst -> Var -> (Subst, Var)
substBndr (CSEnv -> Subst
cs_subst CSEnv
cse) Var
v
addBinders :: CSEnv -> [Var] -> (CSEnv, [Var])
addBinders :: CSEnv -> [Var] -> (CSEnv, [Var])
addBinders CSEnv
cse [Var]
vs = (CSEnv
cse { cs_subst :: Subst
cs_subst = Subst
sub' }, [Var]
vs')
where
(Subst
sub', [Var]
vs') = Subst -> [Var] -> (Subst, [Var])
substBndrs (CSEnv -> Subst
cs_subst CSEnv
cse) [Var]
vs
addRecBinders :: CSEnv -> [Id] -> (CSEnv, [Id])
addRecBinders :: CSEnv -> [Var] -> (CSEnv, [Var])
addRecBinders CSEnv
cse [Var]
vs = (CSEnv
cse { cs_subst :: Subst
cs_subst = Subst
sub' }, [Var]
vs')
where
(Subst
sub', [Var]
vs') = Subst -> [Var] -> (Subst, [Var])
substRecBndrs (CSEnv -> Subst
cs_subst CSEnv
cse) [Var]
vs