{-# LANGUAGE CPP #-}
module SimplEnv (
setMode, getMode, updMode, seDynFlags,
SimplEnv(..), pprSimplEnv,
mkSimplEnv, extendIdSubst,
SimplEnv.extendTvSubst, SimplEnv.extendCvSubst,
zapSubstEnv, setSubstEnv,
getInScope, setInScopeFromE, setInScopeFromF,
setInScopeSet, modifyInScope, addNewInScopeIds,
getSimplRules,
SimplSR(..), mkContEx, substId, lookupRecBndr, refineFromInScope,
simplNonRecBndr, simplNonRecJoinBndr, simplRecBndrs, simplRecJoinBndrs,
simplBinder, simplBinders,
substTy, substTyVar, getTCvSubst,
substCo, substCoVar,
SimplFloats(..), emptyFloats, mkRecFloats,
mkFloatBind, addLetFloats, addJoinFloats, addFloats,
extendFloats, wrapFloats,
doFloatFromRhs, getTopFloatBinds,
LetFloats, letFloatBinds, emptyLetFloats, unitLetFloat,
addLetFlts, mapLetFloats,
JoinFloat, JoinFloats, emptyJoinFloats,
wrapJoinFloats, wrapJoinFloatsX, unitJoinFloat, addJoinFlts
) where
#include "HsVersions.h"
import GhcPrelude
import SimplMonad
import CoreMonad ( SimplMode(..) )
import CoreSyn
import CoreUtils
import Var
import VarEnv
import VarSet
import OrdList
import Id
import MkCore ( mkWildValBinder )
import DynFlags ( DynFlags )
import TysWiredIn
import qualified Type
import Type hiding ( substTy, substTyVar, substTyVarBndr )
import qualified Coercion
import Coercion hiding ( substCo, substCoVar, substCoVarBndr )
import BasicTypes
import MonadUtils
import Outputable
import Util
import UniqFM ( pprUniqFM )
import Data.List
data SimplEnv
= SimplEnv {
SimplEnv -> SimplMode
seMode :: SimplMode
, SimplEnv -> TvSubstEnv
seTvSubst :: TvSubstEnv
, SimplEnv -> CvSubstEnv
seCvSubst :: CvSubstEnv
, SimplEnv -> SimplIdSubst
seIdSubst :: SimplIdSubst
, SimplEnv -> InScopeSet
seInScope :: InScopeSet
}
data SimplFloats
= SimplFloats
{
SimplFloats -> LetFloats
sfLetFloats :: LetFloats
, SimplFloats -> JoinFloats
sfJoinFloats :: JoinFloats
, SimplFloats -> InScopeSet
sfInScope :: InScopeSet
}
instance Outputable SimplFloats where
ppr :: SimplFloats -> SDoc
ppr (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats
lf, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jf, sfInScope :: SimplFloats -> InScopeSet
sfInScope = InScopeSet
is })
= String -> SDoc
text "SimplFloats"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
braces ([SDoc] -> SDoc
vcat [ String -> SDoc
text "lets: " SDoc -> SDoc -> SDoc
<+> LetFloats -> SDoc
forall a. Outputable a => a -> SDoc
ppr LetFloats
lf
, String -> SDoc
text "joins:" SDoc -> SDoc -> SDoc
<+> JoinFloats -> SDoc
forall a. Outputable a => a -> SDoc
ppr JoinFloats
jf
, String -> SDoc
text "in_scope:" SDoc -> SDoc -> SDoc
<+> InScopeSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr InScopeSet
is ])
emptyFloats :: SimplEnv -> SimplFloats
emptyFloats :: SimplEnv -> SimplFloats
emptyFloats env :: SimplEnv
env
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfLetFloats :: LetFloats
sfLetFloats = LetFloats
emptyLetFloats
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
emptyJoinFloats
, sfInScope :: InScopeSet
sfInScope = SimplEnv -> InScopeSet
seInScope SimplEnv
env }
pprSimplEnv :: SimplEnv -> SDoc
pprSimplEnv :: SimplEnv -> SDoc
pprSimplEnv env :: SimplEnv
env
= [SDoc] -> SDoc
vcat [String -> SDoc
text "TvSubst:" SDoc -> SDoc -> SDoc
<+> TvSubstEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr (SimplEnv -> TvSubstEnv
seTvSubst SimplEnv
env),
String -> SDoc
text "CvSubst:" SDoc -> SDoc -> SDoc
<+> CvSubstEnv -> SDoc
forall a. Outputable a => a -> SDoc
ppr (SimplEnv -> CvSubstEnv
seCvSubst SimplEnv
env),
String -> SDoc
text "IdSubst:" SDoc -> SDoc -> SDoc
<+> SDoc
id_subst_doc,
String -> SDoc
text "InScope:" SDoc -> SDoc -> SDoc
<+> SDoc
in_scope_vars_doc
]
where
id_subst_doc :: SDoc
id_subst_doc = (SimplSR -> SDoc) -> SimplIdSubst -> SDoc
forall a. (a -> SDoc) -> UniqFM a -> SDoc
pprUniqFM SimplSR -> SDoc
forall a. Outputable a => a -> SDoc
ppr (SimplEnv -> SimplIdSubst
seIdSubst SimplEnv
env)
in_scope_vars_doc :: SDoc
in_scope_vars_doc = VarSet -> ([Var] -> SDoc) -> SDoc
pprVarSet (InScopeSet -> VarSet
getInScopeVars (SimplEnv -> InScopeSet
seInScope SimplEnv
env))
([SDoc] -> SDoc
vcat ([SDoc] -> SDoc) -> ([Var] -> [SDoc]) -> [Var] -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var -> SDoc) -> [Var] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Var -> SDoc
ppr_one)
ppr_one :: Var -> SDoc
ppr_one v :: Var
v | Var -> Bool
isId Var
v = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
v SDoc -> SDoc -> SDoc
<+> Unfolding -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Var -> Unfolding
idUnfolding Var
v)
| Bool
otherwise = Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
v
type SimplIdSubst = IdEnv SimplSR
data SimplSR
= DoneEx OutExpr (Maybe JoinArity)
| DoneId OutId
| ContEx TvSubstEnv
CvSubstEnv
SimplIdSubst
InExpr
instance Outputable SimplSR where
ppr :: SimplSR -> SDoc
ppr (DoneId v :: Var
v) = String -> SDoc
text "DoneId" SDoc -> SDoc -> SDoc
<+> Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
v
ppr (DoneEx e :: OutExpr
e mj :: Maybe JoinArity
mj) = String -> SDoc
text "DoneEx" SDoc -> SDoc -> SDoc
<> SDoc
pp_mj SDoc -> SDoc -> SDoc
<+> OutExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutExpr
e
where
pp_mj :: SDoc
pp_mj = case Maybe JoinArity
mj of
Nothing -> SDoc
empty
Just n :: JoinArity
n -> SDoc -> SDoc
parens (JoinArity -> SDoc
int JoinArity
n)
ppr (ContEx _tv :: TvSubstEnv
_tv _cv :: CvSubstEnv
_cv _id :: SimplIdSubst
_id e :: OutExpr
e) = [SDoc] -> SDoc
vcat [String -> SDoc
text "ContEx" SDoc -> SDoc -> SDoc
<+> OutExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr OutExpr
e ]
mkSimplEnv :: SimplMode -> SimplEnv
mkSimplEnv :: SimplMode -> SimplEnv
mkSimplEnv mode :: SimplMode
mode
= SimplEnv :: SimplMode
-> TvSubstEnv
-> CvSubstEnv
-> SimplIdSubst
-> InScopeSet
-> SimplEnv
SimplEnv { seMode :: SimplMode
seMode = SimplMode
mode
, seInScope :: InScopeSet
seInScope = InScopeSet
init_in_scope
, seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv
forall a. VarEnv a
emptyVarEnv
, seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv
forall a. VarEnv a
emptyVarEnv
, seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst
forall a. VarEnv a
emptyVarEnv }
init_in_scope :: InScopeSet
init_in_scope :: InScopeSet
init_in_scope = VarSet -> InScopeSet
mkInScopeSet (Var -> VarSet
unitVarSet (Type -> Var
mkWildValBinder Type
unitTy))
getMode :: SimplEnv -> SimplMode
getMode :: SimplEnv -> SimplMode
getMode env :: SimplEnv
env = SimplEnv -> SimplMode
seMode SimplEnv
env
seDynFlags :: SimplEnv -> DynFlags
seDynFlags :: SimplEnv -> DynFlags
seDynFlags env :: SimplEnv
env = SimplMode -> DynFlags
sm_dflags (SimplEnv -> SimplMode
seMode SimplEnv
env)
setMode :: SimplMode -> SimplEnv -> SimplEnv
setMode :: SimplMode -> SimplEnv -> SimplEnv
setMode mode :: SimplMode
mode env :: SimplEnv
env = SimplEnv
env { seMode :: SimplMode
seMode = SimplMode
mode }
updMode :: (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode :: (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode upd :: SimplMode -> SimplMode
upd env :: SimplEnv
env = SimplEnv
env { seMode :: SimplMode
seMode = SimplMode -> SimplMode
upd (SimplEnv -> SimplMode
seMode SimplEnv
env) }
extendIdSubst :: SimplEnv -> Id -> SimplSR -> SimplEnv
extendIdSubst :: SimplEnv -> Var -> SimplSR -> SimplEnv
extendIdSubst env :: SimplEnv
env@(SimplEnv {seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
subst}) var :: Var
var res :: SimplSR
res
= ASSERT2( isId var && not (isCoVar var), ppr var )
SimplEnv
env { seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst -> Var -> SimplSR -> SimplIdSubst
forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv SimplIdSubst
subst Var
var SimplSR
res }
extendTvSubst :: SimplEnv -> TyVar -> Type -> SimplEnv
extendTvSubst :: SimplEnv -> Var -> Type -> SimplEnv
extendTvSubst env :: SimplEnv
env@(SimplEnv {seTvSubst :: SimplEnv -> TvSubstEnv
seTvSubst = TvSubstEnv
tsubst}) var :: Var
var res :: Type
res
= ASSERT2( isTyVar var, ppr var $$ ppr res )
SimplEnv
env {seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv -> Var -> Type -> TvSubstEnv
forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv TvSubstEnv
tsubst Var
var Type
res}
extendCvSubst :: SimplEnv -> CoVar -> Coercion -> SimplEnv
extendCvSubst :: SimplEnv -> Var -> Coercion -> SimplEnv
extendCvSubst env :: SimplEnv
env@(SimplEnv {seCvSubst :: SimplEnv -> CvSubstEnv
seCvSubst = CvSubstEnv
csubst}) var :: Var
var co :: Coercion
co
= ASSERT( isCoVar var )
SimplEnv
env {seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv -> Var -> Coercion -> CvSubstEnv
forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv CvSubstEnv
csubst Var
var Coercion
co}
getInScope :: SimplEnv -> InScopeSet
getInScope :: SimplEnv -> InScopeSet
getInScope env :: SimplEnv
env = SimplEnv -> InScopeSet
seInScope SimplEnv
env
setInScopeSet :: SimplEnv -> InScopeSet -> SimplEnv
setInScopeSet :: SimplEnv -> InScopeSet -> SimplEnv
setInScopeSet env :: SimplEnv
env in_scope :: InScopeSet
in_scope = SimplEnv
env {seInScope :: InScopeSet
seInScope = InScopeSet
in_scope}
setInScopeFromE :: SimplEnv -> SimplEnv -> SimplEnv
setInScopeFromE :: SimplEnv -> SimplEnv -> SimplEnv
setInScopeFromE rhs_env :: SimplEnv
rhs_env here_env :: SimplEnv
here_env = SimplEnv
rhs_env { seInScope :: InScopeSet
seInScope = SimplEnv -> InScopeSet
seInScope SimplEnv
here_env }
setInScopeFromF :: SimplEnv -> SimplFloats -> SimplEnv
setInScopeFromF :: SimplEnv -> SimplFloats -> SimplEnv
setInScopeFromF env :: SimplEnv
env floats :: SimplFloats
floats = SimplEnv
env { seInScope :: InScopeSet
seInScope = SimplFloats -> InScopeSet
sfInScope SimplFloats
floats }
addNewInScopeIds :: SimplEnv -> [CoreBndr] -> SimplEnv
addNewInScopeIds :: SimplEnv -> [Var] -> SimplEnv
addNewInScopeIds env :: SimplEnv
env@(SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope, seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
id_subst }) vs :: [Var]
vs
= SimplEnv
env { seInScope :: InScopeSet
seInScope = InScopeSet
in_scope InScopeSet -> [Var] -> InScopeSet
`extendInScopeSetList` [Var]
vs,
seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst
id_subst SimplIdSubst -> [Var] -> SimplIdSubst
forall a. VarEnv a -> [Var] -> VarEnv a
`delVarEnvList` [Var]
vs }
modifyInScope :: SimplEnv -> CoreBndr -> SimplEnv
modifyInScope :: SimplEnv -> Var -> SimplEnv
modifyInScope env :: SimplEnv
env@(SimplEnv {seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope}) v :: Var
v
= SimplEnv
env {seInScope :: InScopeSet
seInScope = InScopeSet -> Var -> InScopeSet
extendInScopeSet InScopeSet
in_scope Var
v}
zapSubstEnv :: SimplEnv -> SimplEnv
zapSubstEnv :: SimplEnv -> SimplEnv
zapSubstEnv env :: SimplEnv
env = SimplEnv
env {seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv
forall a. VarEnv a
emptyVarEnv, seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv
forall a. VarEnv a
emptyVarEnv, seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst
forall a. VarEnv a
emptyVarEnv}
setSubstEnv :: SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv :: SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv env :: SimplEnv
env tvs :: TvSubstEnv
tvs cvs :: CvSubstEnv
cvs ids :: SimplIdSubst
ids = SimplEnv
env { seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv
tvs, seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv
cvs, seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst
ids }
mkContEx :: SimplEnv -> InExpr -> SimplSR
mkContEx :: SimplEnv -> OutExpr -> SimplSR
mkContEx (SimplEnv { seTvSubst :: SimplEnv -> TvSubstEnv
seTvSubst = TvSubstEnv
tvs, seCvSubst :: SimplEnv -> CvSubstEnv
seCvSubst = CvSubstEnv
cvs, seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
ids }) e :: OutExpr
e = TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> OutExpr -> SimplSR
ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids OutExpr
e
data LetFloats = LetFloats (OrdList OutBind) FloatFlag
type JoinFloat = OutBind
type JoinFloats = OrdList JoinFloat
data FloatFlag
= FltLifted
| FltOkSpec
| FltCareful
instance Outputable LetFloats where
ppr :: LetFloats -> SDoc
ppr (LetFloats binds :: JoinFloats
binds ff :: FloatFlag
ff) = FloatFlag -> SDoc
forall a. Outputable a => a -> SDoc
ppr FloatFlag
ff SDoc -> SDoc -> SDoc
$$ [OutBind] -> SDoc
forall a. Outputable a => a -> SDoc
ppr (JoinFloats -> [OutBind]
forall a. OrdList a -> [a]
fromOL JoinFloats
binds)
instance Outputable FloatFlag where
ppr :: FloatFlag -> SDoc
ppr FltLifted = String -> SDoc
text "FltLifted"
ppr FltOkSpec = String -> SDoc
text "FltOkSpec"
ppr FltCareful = String -> SDoc
text "FltCareful"
andFF :: FloatFlag -> FloatFlag -> FloatFlag
andFF :: FloatFlag -> FloatFlag -> FloatFlag
andFF FltCareful _ = FloatFlag
FltCareful
andFF FltOkSpec FltCareful = FloatFlag
FltCareful
andFF FltOkSpec _ = FloatFlag
FltOkSpec
andFF FltLifted flt :: FloatFlag
flt = FloatFlag
flt
doFloatFromRhs :: TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> OutExpr -> Bool
doFloatFromRhs :: TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> OutExpr -> Bool
doFloatFromRhs lvl :: TopLevelFlag
lvl rec :: RecFlag
rec str :: Bool
str (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats fs :: JoinFloats
fs ff :: FloatFlag
ff }) rhs :: OutExpr
rhs
= Bool -> Bool
not (JoinFloats -> Bool
forall a. OrdList a -> Bool
isNilOL JoinFloats
fs) Bool -> Bool -> Bool
&& Bool
want_to_float Bool -> Bool -> Bool
&& Bool
can_float
where
want_to_float :: Bool
want_to_float = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
lvl Bool -> Bool -> Bool
|| OutExpr -> Bool
exprIsCheap OutExpr
rhs Bool -> Bool -> Bool
|| OutExpr -> Bool
exprIsExpandable OutExpr
rhs
can_float :: Bool
can_float = case FloatFlag
ff of
FltLifted -> Bool
True
FltOkSpec -> TopLevelFlag -> Bool
isNotTopLevel TopLevelFlag
lvl Bool -> Bool -> Bool
&& RecFlag -> Bool
isNonRec RecFlag
rec
FltCareful -> TopLevelFlag -> Bool
isNotTopLevel TopLevelFlag
lvl Bool -> Bool -> Bool
&& RecFlag -> Bool
isNonRec RecFlag
rec Bool -> Bool -> Bool
&& Bool
str
emptyLetFloats :: LetFloats
emptyLetFloats :: LetFloats
emptyLetFloats = JoinFloats -> FloatFlag -> LetFloats
LetFloats JoinFloats
forall a. OrdList a
nilOL FloatFlag
FltLifted
emptyJoinFloats :: JoinFloats
emptyJoinFloats :: JoinFloats
emptyJoinFloats = JoinFloats
forall a. OrdList a
nilOL
unitLetFloat :: OutBind -> LetFloats
unitLetFloat :: OutBind -> LetFloats
unitLetFloat bind :: OutBind
bind = ASSERT(all (not . isJoinId) (bindersOf bind))
JoinFloats -> FloatFlag -> LetFloats
LetFloats (OutBind -> JoinFloats
forall a. a -> OrdList a
unitOL OutBind
bind) (OutBind -> FloatFlag
flag OutBind
bind)
where
flag :: OutBind -> FloatFlag
flag (Rec {}) = FloatFlag
FltLifted
flag (NonRec bndr :: Var
bndr rhs :: OutExpr
rhs)
| Bool -> Bool
not (Var -> Bool
isStrictId Var
bndr) = FloatFlag
FltLifted
| OutExpr -> Bool
exprIsTickedString OutExpr
rhs = FloatFlag
FltLifted
| OutExpr -> Bool
exprOkForSpeculation OutExpr
rhs = FloatFlag
FltOkSpec
| Bool
otherwise = ASSERT2( not (isUnliftedType (idType bndr)), ppr bndr )
FloatFlag
FltCareful
unitJoinFloat :: OutBind -> JoinFloats
unitJoinFloat :: OutBind -> JoinFloats
unitJoinFloat bind :: OutBind
bind = ASSERT(all isJoinId (bindersOf bind))
OutBind -> JoinFloats
forall a. a -> OrdList a
unitOL OutBind
bind
mkFloatBind :: SimplEnv -> OutBind -> (SimplFloats, SimplEnv)
mkFloatBind :: SimplEnv -> OutBind -> (SimplFloats, SimplEnv)
mkFloatBind env :: SimplEnv
env bind :: OutBind
bind
= (SimplFloats
floats, SimplEnv
env { seInScope :: InScopeSet
seInScope = InScopeSet
in_scope' })
where
floats :: SimplFloats
floats
| OutBind -> Bool
isJoinBind OutBind
bind
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfLetFloats :: LetFloats
sfLetFloats = LetFloats
emptyLetFloats
, sfJoinFloats :: JoinFloats
sfJoinFloats = OutBind -> JoinFloats
unitJoinFloat OutBind
bind
, sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope' }
| Bool
otherwise
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfLetFloats :: LetFloats
sfLetFloats = OutBind -> LetFloats
unitLetFloat OutBind
bind
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
emptyJoinFloats
, sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope' }
in_scope' :: InScopeSet
in_scope' = SimplEnv -> InScopeSet
seInScope SimplEnv
env InScopeSet -> OutBind -> InScopeSet
`extendInScopeSetBind` OutBind
bind
extendFloats :: SimplFloats -> OutBind -> SimplFloats
extendFloats :: SimplFloats -> OutBind -> SimplFloats
extendFloats (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats
floats
, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jfloats
, sfInScope :: SimplFloats -> InScopeSet
sfInScope = InScopeSet
in_scope })
bind :: OutBind
bind
| OutBind -> Bool
isJoinBind OutBind
bind
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope'
, sfLetFloats :: LetFloats
sfLetFloats = LetFloats
floats
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
jfloats' }
| Bool
otherwise
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope'
, sfLetFloats :: LetFloats
sfLetFloats = LetFloats
floats'
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
jfloats }
where
in_scope' :: InScopeSet
in_scope' = InScopeSet
in_scope InScopeSet -> OutBind -> InScopeSet
`extendInScopeSetBind` OutBind
bind
floats' :: LetFloats
floats' = LetFloats
floats LetFloats -> LetFloats -> LetFloats
`addLetFlts` OutBind -> LetFloats
unitLetFloat OutBind
bind
jfloats' :: JoinFloats
jfloats' = JoinFloats
jfloats JoinFloats -> JoinFloats -> JoinFloats
`addJoinFlts` OutBind -> JoinFloats
unitJoinFloat OutBind
bind
addLetFloats :: SimplFloats -> LetFloats -> SimplFloats
addLetFloats :: SimplFloats -> LetFloats -> SimplFloats
addLetFloats floats :: SimplFloats
floats let_floats :: LetFloats
let_floats@(LetFloats binds :: JoinFloats
binds _)
= SimplFloats
floats { sfLetFloats :: LetFloats
sfLetFloats = SimplFloats -> LetFloats
sfLetFloats SimplFloats
floats LetFloats -> LetFloats -> LetFloats
`addLetFlts` LetFloats
let_floats
, sfInScope :: InScopeSet
sfInScope = (InScopeSet -> OutBind -> InScopeSet)
-> InScopeSet -> JoinFloats -> InScopeSet
forall b a. (b -> a -> b) -> b -> OrdList a -> b
foldlOL InScopeSet -> OutBind -> InScopeSet
extendInScopeSetBind
(SimplFloats -> InScopeSet
sfInScope SimplFloats
floats) JoinFloats
binds }
addJoinFloats :: SimplFloats -> JoinFloats -> SimplFloats
addJoinFloats :: SimplFloats -> JoinFloats -> SimplFloats
addJoinFloats floats :: SimplFloats
floats join_floats :: JoinFloats
join_floats
= SimplFloats
floats { sfJoinFloats :: JoinFloats
sfJoinFloats = SimplFloats -> JoinFloats
sfJoinFloats SimplFloats
floats JoinFloats -> JoinFloats -> JoinFloats
`addJoinFlts` JoinFloats
join_floats
, sfInScope :: InScopeSet
sfInScope = (InScopeSet -> OutBind -> InScopeSet)
-> InScopeSet -> JoinFloats -> InScopeSet
forall b a. (b -> a -> b) -> b -> OrdList a -> b
foldlOL InScopeSet -> OutBind -> InScopeSet
extendInScopeSetBind
(SimplFloats -> InScopeSet
sfInScope SimplFloats
floats) JoinFloats
join_floats }
extendInScopeSetBind :: InScopeSet -> CoreBind -> InScopeSet
extendInScopeSetBind :: InScopeSet -> OutBind -> InScopeSet
extendInScopeSetBind in_scope :: InScopeSet
in_scope bind :: OutBind
bind
= InScopeSet -> [Var] -> InScopeSet
extendInScopeSetList InScopeSet
in_scope (OutBind -> [Var]
forall b. Bind b -> [b]
bindersOf OutBind
bind)
addFloats :: SimplFloats -> SimplFloats -> SimplFloats
addFloats :: SimplFloats -> SimplFloats -> SimplFloats
addFloats (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats
lf1, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jf1 })
(SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats
lf2, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jf2, sfInScope :: SimplFloats -> InScopeSet
sfInScope = InScopeSet
in_scope })
= SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfLetFloats :: LetFloats
sfLetFloats = LetFloats
lf1 LetFloats -> LetFloats -> LetFloats
`addLetFlts` LetFloats
lf2
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
jf1 JoinFloats -> JoinFloats -> JoinFloats
`addJoinFlts` JoinFloats
jf2
, sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope }
addLetFlts :: LetFloats -> LetFloats -> LetFloats
addLetFlts :: LetFloats -> LetFloats -> LetFloats
addLetFlts (LetFloats bs1 :: JoinFloats
bs1 l1 :: FloatFlag
l1) (LetFloats bs2 :: JoinFloats
bs2 l2 :: FloatFlag
l2)
= JoinFloats -> FloatFlag -> LetFloats
LetFloats (JoinFloats
bs1 JoinFloats -> JoinFloats -> JoinFloats
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` JoinFloats
bs2) (FloatFlag
l1 FloatFlag -> FloatFlag -> FloatFlag
`andFF` FloatFlag
l2)
letFloatBinds :: LetFloats -> [CoreBind]
letFloatBinds :: LetFloats -> [OutBind]
letFloatBinds (LetFloats bs :: JoinFloats
bs _) = JoinFloats -> [OutBind]
forall a. OrdList a -> [a]
fromOL JoinFloats
bs
addJoinFlts :: JoinFloats -> JoinFloats -> JoinFloats
addJoinFlts :: JoinFloats -> JoinFloats -> JoinFloats
addJoinFlts = JoinFloats -> JoinFloats -> JoinFloats
forall a. OrdList a -> OrdList a -> OrdList a
appOL
mkRecFloats :: SimplFloats -> SimplFloats
mkRecFloats :: SimplFloats -> SimplFloats
mkRecFloats floats :: SimplFloats
floats@(SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats bs :: JoinFloats
bs ff :: FloatFlag
ff
, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jbs
, sfInScope :: SimplFloats -> InScopeSet
sfInScope = InScopeSet
in_scope })
= ASSERT2( case ff of { FltLifted -> True; _ -> False }, ppr (fromOL bs) )
ASSERT2( isNilOL bs || isNilOL jbs, ppr floats )
SimplFloats :: LetFloats -> JoinFloats -> InScopeSet -> SimplFloats
SimplFloats { sfLetFloats :: LetFloats
sfLetFloats = LetFloats
floats'
, sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
jfloats'
, sfInScope :: InScopeSet
sfInScope = InScopeSet
in_scope }
where
floats' :: LetFloats
floats' | JoinFloats -> Bool
forall a. OrdList a -> Bool
isNilOL JoinFloats
bs = LetFloats
emptyLetFloats
| Bool
otherwise = OutBind -> LetFloats
unitLetFloat ([(Var, OutExpr)] -> OutBind
forall b. [(b, Expr b)] -> Bind b
Rec ([OutBind] -> [(Var, OutExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds (JoinFloats -> [OutBind]
forall a. OrdList a -> [a]
fromOL JoinFloats
bs)))
jfloats' :: JoinFloats
jfloats' | JoinFloats -> Bool
forall a. OrdList a -> Bool
isNilOL JoinFloats
jbs = JoinFloats
emptyJoinFloats
| Bool
otherwise = OutBind -> JoinFloats
unitJoinFloat ([(Var, OutExpr)] -> OutBind
forall b. [(b, Expr b)] -> Bind b
Rec ([OutBind] -> [(Var, OutExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds (JoinFloats -> [OutBind]
forall a. OrdList a -> [a]
fromOL JoinFloats
jbs)))
wrapFloats :: SimplFloats -> OutExpr -> OutExpr
wrapFloats :: SimplFloats -> OutExpr -> OutExpr
wrapFloats (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats bs :: JoinFloats
bs _
, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jbs }) body :: OutExpr
body
= (OutBind -> OutExpr -> OutExpr) -> OutExpr -> JoinFloats -> OutExpr
forall a b. (a -> b -> b) -> b -> OrdList a -> b
foldrOL OutBind -> OutExpr -> OutExpr
forall b. Bind b -> Expr b -> Expr b
Let (JoinFloats -> OutExpr -> OutExpr
wrapJoinFloats JoinFloats
jbs OutExpr
body) JoinFloats
bs
wrapJoinFloatsX :: SimplFloats -> OutExpr -> (SimplFloats, OutExpr)
wrapJoinFloatsX :: SimplFloats -> OutExpr -> (SimplFloats, OutExpr)
wrapJoinFloatsX floats :: SimplFloats
floats body :: OutExpr
body
= ( SimplFloats
floats { sfJoinFloats :: JoinFloats
sfJoinFloats = JoinFloats
emptyJoinFloats }
, JoinFloats -> OutExpr -> OutExpr
wrapJoinFloats (SimplFloats -> JoinFloats
sfJoinFloats SimplFloats
floats) OutExpr
body )
wrapJoinFloats :: JoinFloats -> OutExpr -> OutExpr
wrapJoinFloats :: JoinFloats -> OutExpr -> OutExpr
wrapJoinFloats join_floats :: JoinFloats
join_floats body :: OutExpr
body
= (OutBind -> OutExpr -> OutExpr) -> OutExpr -> JoinFloats -> OutExpr
forall a b. (a -> b -> b) -> b -> OrdList a -> b
foldrOL OutBind -> OutExpr -> OutExpr
forall b. Bind b -> Expr b -> Expr b
Let OutExpr
body JoinFloats
join_floats
getTopFloatBinds :: SimplFloats -> [CoreBind]
getTopFloatBinds :: SimplFloats -> [OutBind]
getTopFloatBinds (SimplFloats { sfLetFloats :: SimplFloats -> LetFloats
sfLetFloats = LetFloats
lbs
, sfJoinFloats :: SimplFloats -> JoinFloats
sfJoinFloats = JoinFloats
jbs})
= ASSERT( isNilOL jbs )
LetFloats -> [OutBind]
letFloatBinds LetFloats
lbs
mapLetFloats :: LetFloats -> ((Id,CoreExpr) -> (Id,CoreExpr)) -> LetFloats
mapLetFloats :: LetFloats -> ((Var, OutExpr) -> (Var, OutExpr)) -> LetFloats
mapLetFloats (LetFloats fs :: JoinFloats
fs ff :: FloatFlag
ff) fun :: (Var, OutExpr) -> (Var, OutExpr)
fun
= JoinFloats -> FloatFlag -> LetFloats
LetFloats ((OutBind -> OutBind) -> JoinFloats -> JoinFloats
forall a b. (a -> b) -> OrdList a -> OrdList b
mapOL OutBind -> OutBind
app JoinFloats
fs) FloatFlag
ff
where
app :: OutBind -> OutBind
app (NonRec b :: Var
b e :: OutExpr
e) = case (Var, OutExpr) -> (Var, OutExpr)
fun (Var
b,OutExpr
e) of (b' :: Var
b',e' :: OutExpr
e') -> Var -> OutExpr -> OutBind
forall b. b -> Expr b -> Bind b
NonRec Var
b' OutExpr
e'
app (Rec bs :: [(Var, OutExpr)]
bs) = [(Var, OutExpr)] -> OutBind
forall b. [(b, Expr b)] -> Bind b
Rec (((Var, OutExpr) -> (Var, OutExpr))
-> [(Var, OutExpr)] -> [(Var, OutExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (Var, OutExpr) -> (Var, OutExpr)
fun [(Var, OutExpr)]
bs)
substId :: SimplEnv -> InId -> SimplSR
substId :: SimplEnv -> Var -> SimplSR
substId (SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope, seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
ids }) v :: Var
v
= case SimplIdSubst -> Var -> Maybe SimplSR
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv SimplIdSubst
ids Var
v of
Nothing -> Var -> SimplSR
DoneId (InScopeSet -> Var -> Var
refineFromInScope InScopeSet
in_scope Var
v)
Just (DoneId v :: Var
v) -> Var -> SimplSR
DoneId (InScopeSet -> Var -> Var
refineFromInScope InScopeSet
in_scope Var
v)
Just res :: SimplSR
res -> SimplSR
res
refineFromInScope :: InScopeSet -> Var -> Var
refineFromInScope :: InScopeSet -> Var -> Var
refineFromInScope in_scope :: InScopeSet
in_scope v :: Var
v
| Var -> Bool
isLocalId Var
v = case InScopeSet -> Var -> Maybe Var
lookupInScope InScopeSet
in_scope Var
v of
Just v' :: Var
v' -> Var
v'
Nothing -> WARN( True, ppr v ) v
| Bool
otherwise = Var
v
lookupRecBndr :: SimplEnv -> InId -> OutId
lookupRecBndr :: SimplEnv -> Var -> Var
lookupRecBndr (SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope, seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
ids }) v :: Var
v
= case SimplIdSubst -> Var -> Maybe SimplSR
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv SimplIdSubst
ids Var
v of
Just (DoneId v :: Var
v) -> Var
v
Just _ -> String -> SDoc -> Var
forall a. HasCallStack => String -> SDoc -> a
pprPanic "lookupRecBndr" (Var -> SDoc
forall a. Outputable a => a -> SDoc
ppr Var
v)
Nothing -> InScopeSet -> Var -> Var
refineFromInScope InScopeSet
in_scope Var
v
simplBinders :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
simplBinders :: SimplEnv -> [Var] -> SimplM (SimplEnv, [Var])
simplBinders env :: SimplEnv
env bndrs :: [Var]
bndrs = (SimplEnv -> Var -> SimplM (SimplEnv, Var))
-> SimplEnv -> [Var] -> SimplM (SimplEnv, [Var])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM SimplEnv -> Var -> SimplM (SimplEnv, Var)
simplBinder SimplEnv
env [Var]
bndrs
simplBinder :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
simplBinder :: SimplEnv -> Var -> SimplM (SimplEnv, Var)
simplBinder env :: SimplEnv
env bndr :: Var
bndr
| Var -> Bool
isTyVar Var
bndr = do { let (env' :: SimplEnv
env', tv :: Var
tv) = SimplEnv -> Var -> (SimplEnv, Var)
substTyVarBndr SimplEnv
env Var
bndr
; Var -> ()
seqTyVar Var
tv () -> SimplM (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall a b. a -> b -> b
`seq` (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env', Var
tv) }
| Bool
otherwise = do { let (env' :: SimplEnv
env', id :: Var
id) = Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr Maybe Type
forall a. Maybe a
Nothing SimplEnv
env Var
bndr
; Var -> ()
seqId Var
id () -> SimplM (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall a b. a -> b -> b
`seq` (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env', Var
id) }
simplNonRecBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
simplNonRecBndr :: SimplEnv -> Var -> SimplM (SimplEnv, Var)
simplNonRecBndr env :: SimplEnv
env id :: Var
id
= do { let (env1 :: SimplEnv
env1, id1 :: Var
id1) = Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr Maybe Type
forall a. Maybe a
Nothing SimplEnv
env Var
id
; Var -> ()
seqId Var
id1 () -> SimplM (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall a b. a -> b -> b
`seq` (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env1, Var
id1) }
simplNonRecJoinBndr :: SimplEnv -> OutType -> InBndr
-> SimplM (SimplEnv, OutBndr)
simplNonRecJoinBndr :: SimplEnv -> Type -> Var -> SimplM (SimplEnv, Var)
simplNonRecJoinBndr env :: SimplEnv
env res_ty :: Type
res_ty id :: Var
id
= do { let (env1 :: SimplEnv
env1, id1 :: Var
id1) = Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr (Type -> Maybe Type
forall a. a -> Maybe a
Just Type
res_ty) SimplEnv
env Var
id
; Var -> ()
seqId Var
id1 () -> SimplM (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall a b. a -> b -> b
`seq` (SimplEnv, Var) -> SimplM (SimplEnv, Var)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env1, Var
id1) }
simplRecBndrs :: SimplEnv -> [InBndr] -> SimplM SimplEnv
simplRecBndrs :: SimplEnv -> [Var] -> SimplM SimplEnv
simplRecBndrs env :: SimplEnv
env@(SimplEnv {}) ids :: [Var]
ids
= ASSERT(all (not . isJoinId) ids)
do { let (env1 :: SimplEnv
env1, ids1 :: [Var]
ids1) = (SimplEnv -> Var -> (SimplEnv, Var))
-> SimplEnv -> [Var] -> (SimplEnv, [Var])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL (Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr Maybe Type
forall a. Maybe a
Nothing) SimplEnv
env [Var]
ids
; [Var] -> ()
seqIds [Var]
ids1 () -> SimplM SimplEnv -> SimplM SimplEnv
forall a b. a -> b -> b
`seq` SimplEnv -> SimplM SimplEnv
forall (m :: * -> *) a. Monad m => a -> m a
return SimplEnv
env1 }
simplRecJoinBndrs :: SimplEnv -> OutType -> [InBndr] -> SimplM SimplEnv
simplRecJoinBndrs :: SimplEnv -> Type -> [Var] -> SimplM SimplEnv
simplRecJoinBndrs env :: SimplEnv
env@(SimplEnv {}) res_ty :: Type
res_ty ids :: [Var]
ids
= ASSERT(all isJoinId ids)
do { let (env1 :: SimplEnv
env1, ids1 :: [Var]
ids1) = (SimplEnv -> Var -> (SimplEnv, Var))
-> SimplEnv -> [Var] -> (SimplEnv, [Var])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL (Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr (Type -> Maybe Type
forall a. a -> Maybe a
Just Type
res_ty)) SimplEnv
env [Var]
ids
; [Var] -> ()
seqIds [Var]
ids1 () -> SimplM SimplEnv -> SimplM SimplEnv
forall a b. a -> b -> b
`seq` SimplEnv -> SimplM SimplEnv
forall (m :: * -> *) a. Monad m => a -> m a
return SimplEnv
env1 }
substIdBndr :: Maybe OutType -> SimplEnv -> InBndr -> (SimplEnv, OutBndr)
substIdBndr :: Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substIdBndr new_res_ty :: Maybe Type
new_res_ty env :: SimplEnv
env bndr :: Var
bndr
| Var -> Bool
isCoVar Var
bndr = SimplEnv -> Var -> (SimplEnv, Var)
substCoVarBndr SimplEnv
env Var
bndr
| Bool
otherwise = Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substNonCoVarIdBndr Maybe Type
new_res_ty SimplEnv
env Var
bndr
substNonCoVarIdBndr
:: Maybe OutType
-> SimplEnv
-> InBndr
-> (SimplEnv, OutBndr)
substNonCoVarIdBndr :: Maybe Type -> SimplEnv -> Var -> (SimplEnv, Var)
substNonCoVarIdBndr new_res_ty :: Maybe Type
new_res_ty
env :: SimplEnv
env@(SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope
, seIdSubst :: SimplEnv -> SimplIdSubst
seIdSubst = SimplIdSubst
id_subst })
old_id :: Var
old_id
= ASSERT2( not (isCoVar old_id), ppr old_id )
(SimplEnv
env { seInScope :: InScopeSet
seInScope = InScopeSet
in_scope InScopeSet -> Var -> InScopeSet
`extendInScopeSet` Var
new_id,
seIdSubst :: SimplIdSubst
seIdSubst = SimplIdSubst
new_subst }, Var
new_id)
where
id1 :: Var
id1 = InScopeSet -> Var -> Var
uniqAway InScopeSet
in_scope Var
old_id
id2 :: Var
id2 = SimplEnv -> Var -> Var
substIdType SimplEnv
env Var
id1
id3 :: Var
id3 | Just res_ty :: Type
res_ty <- Maybe Type
new_res_ty
= Var
id2 Var -> Type -> Var
`setIdType` JoinArity -> Type -> Type -> Type
setJoinResTy (Var -> JoinArity
idJoinArity Var
id2) Type
res_ty (Var -> Type
idType Var
id2)
| Bool
otherwise
= Var
id2
new_id :: Var
new_id = Var -> Var
zapFragileIdInfo Var
id3
new_subst :: SimplIdSubst
new_subst | Var
new_id Var -> Var -> Bool
forall a. Eq a => a -> a -> Bool
/= Var
old_id
= SimplIdSubst -> Var -> SimplSR -> SimplIdSubst
forall a. VarEnv a -> Var -> a -> VarEnv a
extendVarEnv SimplIdSubst
id_subst Var
old_id (Var -> SimplSR
DoneId Var
new_id)
| Bool
otherwise
= SimplIdSubst -> Var -> SimplIdSubst
forall a. VarEnv a -> Var -> VarEnv a
delVarEnv SimplIdSubst
id_subst Var
old_id
seqTyVar :: TyVar -> ()
seqTyVar :: Var -> ()
seqTyVar b :: Var
b = Var
b Var -> () -> ()
forall a b. a -> b -> b
`seq` ()
seqId :: Id -> ()
seqId :: Var -> ()
seqId id :: Var
id = Type -> ()
seqType (Var -> Type
idType Var
id) () -> () -> ()
forall a b. a -> b -> b
`seq`
HasDebugCallStack => Var -> IdInfo
Var -> IdInfo
idInfo Var
id IdInfo -> () -> ()
forall a b. a -> b -> b
`seq`
()
seqIds :: [Id] -> ()
seqIds :: [Var] -> ()
seqIds [] = ()
seqIds (id :: Var
id:ids :: [Var]
ids) = Var -> ()
seqId Var
id () -> () -> ()
forall a b. a -> b -> b
`seq` [Var] -> ()
seqIds [Var]
ids
getTCvSubst :: SimplEnv -> TCvSubst
getTCvSubst :: SimplEnv -> TCvSubst
getTCvSubst (SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope, seTvSubst :: SimplEnv -> TvSubstEnv
seTvSubst = TvSubstEnv
tv_env
, seCvSubst :: SimplEnv -> CvSubstEnv
seCvSubst = CvSubstEnv
cv_env })
= InScopeSet -> (TvSubstEnv, CvSubstEnv) -> TCvSubst
mkTCvSubst InScopeSet
in_scope (TvSubstEnv
tv_env, CvSubstEnv
cv_env)
substTy :: SimplEnv -> Type -> Type
substTy :: SimplEnv -> Type -> Type
substTy env :: SimplEnv
env ty :: Type
ty = HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
Type.substTy (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Type
ty
substTyVar :: SimplEnv -> TyVar -> Type
substTyVar :: SimplEnv -> Var -> Type
substTyVar env :: SimplEnv
env tv :: Var
tv = TCvSubst -> Var -> Type
Type.substTyVar (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Var
tv
substTyVarBndr :: SimplEnv -> TyVar -> (SimplEnv, TyVar)
substTyVarBndr :: SimplEnv -> Var -> (SimplEnv, Var)
substTyVarBndr env :: SimplEnv
env tv :: Var
tv
= case HasCallStack => TCvSubst -> Var -> (TCvSubst, Var)
TCvSubst -> Var -> (TCvSubst, Var)
Type.substTyVarBndr (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Var
tv of
(TCvSubst in_scope' :: InScopeSet
in_scope' tv_env' :: TvSubstEnv
tv_env' cv_env' :: CvSubstEnv
cv_env', tv' :: Var
tv')
-> (SimplEnv
env { seInScope :: InScopeSet
seInScope = InScopeSet
in_scope', seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv
tv_env', seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv
cv_env' }, Var
tv')
substCoVar :: SimplEnv -> CoVar -> Coercion
substCoVar :: SimplEnv -> Var -> Coercion
substCoVar env :: SimplEnv
env tv :: Var
tv = TCvSubst -> Var -> Coercion
Coercion.substCoVar (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Var
tv
substCoVarBndr :: SimplEnv -> CoVar -> (SimplEnv, CoVar)
substCoVarBndr :: SimplEnv -> Var -> (SimplEnv, Var)
substCoVarBndr env :: SimplEnv
env cv :: Var
cv
= case HasCallStack => TCvSubst -> Var -> (TCvSubst, Var)
TCvSubst -> Var -> (TCvSubst, Var)
Coercion.substCoVarBndr (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Var
cv of
(TCvSubst in_scope' :: InScopeSet
in_scope' tv_env' :: TvSubstEnv
tv_env' cv_env' :: CvSubstEnv
cv_env', cv' :: Var
cv')
-> (SimplEnv
env { seInScope :: InScopeSet
seInScope = InScopeSet
in_scope', seTvSubst :: TvSubstEnv
seTvSubst = TvSubstEnv
tv_env', seCvSubst :: CvSubstEnv
seCvSubst = CvSubstEnv
cv_env' }, Var
cv')
substCo :: SimplEnv -> Coercion -> Coercion
substCo :: SimplEnv -> Coercion -> Coercion
substCo env :: SimplEnv
env co :: Coercion
co = HasCallStack => TCvSubst -> Coercion -> Coercion
TCvSubst -> Coercion -> Coercion
Coercion.substCo (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Coercion
co
substIdType :: SimplEnv -> Id -> Id
substIdType :: SimplEnv -> Var -> Var
substIdType (SimplEnv { seInScope :: SimplEnv -> InScopeSet
seInScope = InScopeSet
in_scope, seTvSubst :: SimplEnv -> TvSubstEnv
seTvSubst = TvSubstEnv
tv_env, seCvSubst :: SimplEnv -> CvSubstEnv
seCvSubst = CvSubstEnv
cv_env }) id :: Var
id
| (TvSubstEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv TvSubstEnv
tv_env Bool -> Bool -> Bool
&& CvSubstEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv CvSubstEnv
cv_env)
Bool -> Bool -> Bool
|| Type -> Bool
noFreeVarsOfType Type
old_ty
= Var
id
| Bool
otherwise = Var -> Type -> Var
Id.setIdType Var
id (HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
Type.substTy (InScopeSet -> TvSubstEnv -> CvSubstEnv -> TCvSubst
TCvSubst InScopeSet
in_scope TvSubstEnv
tv_env CvSubstEnv
cv_env) Type
old_ty)
where
old_ty :: Type
old_ty = Var -> Type
idType Var
id