{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates -Wno-incomplete-uni-patterns #-}
module GHC.Core.Opt.Simplify ( simplTopBinds, simplExpr, simplRules ) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Platform
import GHC.Driver.Session
import GHC.Core.Opt.Simplify.Monad
import GHC.Core.Type hiding ( substTy, substTyVar, extendTvSubst, extendCvSubst )
import GHC.Core.Opt.Simplify.Env
import GHC.Core.Opt.Simplify.Utils
import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr )
import GHC.Core.FamInstEnv ( FamInstEnv )
import GHC.Types.Literal ( litIsLifted )
import GHC.Types.Id
import GHC.Types.Id.Make ( seqId )
import GHC.Core.Make ( FloatBind, mkImpossibleExpr, castBottomExpr )
import qualified GHC.Core.Make
import GHC.Types.Id.Info
import GHC.Types.Name ( mkSystemVarName, isExternalName, getOccFS )
import GHC.Core.Coercion hiding ( substCo, substCoVar )
import GHC.Core.Coercion.Opt ( optCoercion )
import GHC.Core.FamInstEnv ( topNormaliseType_maybe )
import GHC.Core.DataCon
( DataCon, dataConWorkId, dataConRepStrictness
, dataConRepArgTys, isUnboxedTupleCon
, StrictnessMark (..) )
import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) )
import GHC.Core
import GHC.Builtin.Types.Prim( realWorldStatePrimTy )
import GHC.Builtin.Names( runRWKey )
import GHC.Types.Demand ( StrictSig(..), Demand, dmdTypeDepth, isStrictDmd
, mkClosedStrictSig, topDmd, seqDmd, botDiv )
import GHC.Types.Cpr ( mkCprSig, botCpr )
import GHC.Core.Ppr ( pprCoreExpr )
import GHC.Types.Unique ( hasKey )
import GHC.Core.Unfold
import GHC.Core.Utils
import GHC.Core.Opt.Arity ( ArityType(..), arityTypeArity, isBotArityType
, idArityType, etaExpandAT )
import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg
, joinPointBinding_maybe, joinPointBindings_maybe )
import GHC.Core.FVs ( mkRuleInfo )
import GHC.Core.Rules ( lookupRule, getRules, initRuleOpts )
import GHC.Types.Basic
import GHC.Utils.Monad ( mapAccumLM, liftIO )
import GHC.Types.Var ( isTyCoVar )
import GHC.Data.Maybe ( orElse, isNothing )
import Control.Monad
import GHC.Utils.Outputable
import GHC.Data.FastString
import GHC.Utils.Misc
import GHC.Utils.Error
import GHC.Unit.Module ( moduleName, pprModuleName )
import GHC.Core.Multiplicity
import GHC.Builtin.PrimOps ( PrimOp (SeqOp) )
simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simplTopBinds SimplEnv
env0 [InBind]
binds0
= do {
; SimplEnv
env1 <- {-#SCC "simplTopBinds-simplRecBndrs" #-} SimplEnv -> [Id] -> SimplM SimplEnv
simplRecBndrs SimplEnv
env0 ([InBind] -> [Id]
forall b. [Bind b] -> [b]
bindersOfBinds [InBind]
binds0)
; (SimplFloats
floats, SimplEnv
env2) <- {-#SCC "simplTopBinds-simpl_binds" #-} SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env1 [InBind]
binds0
; Tick -> SimplM ()
freeTick Tick
SimplifierDone
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, SimplEnv
env2) }
where
simpl_binds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env [] = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
simpl_binds SimplEnv
env (InBind
bind:[InBind]
binds) = do { (SimplFloats
float, SimplEnv
env1) <- SimplEnv -> InBind -> SimplM (SimplFloats, SimplEnv)
simpl_bind SimplEnv
env InBind
bind
; (SimplFloats
floats, SimplEnv
env2) <- SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv)
simpl_binds SimplEnv
env1 [InBind]
binds
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
float SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats, SimplEnv
env2) }
simpl_bind :: SimplEnv -> InBind -> SimplM (SimplFloats, SimplEnv)
simpl_bind SimplEnv
env (Rec [(Id, CoreExpr)]
pairs)
= SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(Id, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env TopLevelFlag
TopLevel MaybeJoinCont
forall a. Maybe a
Nothing [(Id, CoreExpr)]
pairs
simpl_bind SimplEnv
env (NonRec Id
b CoreExpr
r)
= do { (SimplEnv
env', Id
b') <- SimplEnv -> Id -> Id -> MaybeJoinCont -> SimplM (SimplEnv, Id)
addBndrRules SimplEnv
env Id
b (SimplEnv -> Id -> Id
lookupRecBndr SimplEnv
env Id
b) MaybeJoinCont
forall a. Maybe a
Nothing
; SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env' TopLevelFlag
TopLevel RecFlag
NonRecursive MaybeJoinCont
forall a. Maybe a
Nothing Id
b Id
b' CoreExpr
r }
simplRecBind :: SimplEnv -> TopLevelFlag -> MaybeJoinCont
-> [(InId, InExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(Id, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env0 TopLevelFlag
top_lvl MaybeJoinCont
mb_cont [(Id, CoreExpr)]
pairs0
= do { (SimplEnv
env_with_info, [(Id, Id, CoreExpr)]
triples) <- (SimplEnv
-> (Id, CoreExpr) -> SimplM (SimplEnv, (Id, Id, CoreExpr)))
-> SimplEnv
-> [(Id, CoreExpr)]
-> SimplM (SimplEnv, [(Id, Id, CoreExpr)])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM SimplEnv -> (Id, CoreExpr) -> SimplM (SimplEnv, (Id, Id, CoreExpr))
add_rules SimplEnv
env0 [(Id, CoreExpr)]
pairs0
; (SimplFloats
rec_floats, SimplEnv
env1) <- SimplEnv -> [(Id, Id, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env_with_info [(Id, Id, CoreExpr)]
triples
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats -> SimplFloats
mkRecFloats SimplFloats
rec_floats, SimplEnv
env1) }
where
add_rules :: SimplEnv -> (InBndr,InExpr) -> SimplM (SimplEnv, (InBndr, OutBndr, InExpr))
add_rules :: SimplEnv -> (Id, CoreExpr) -> SimplM (SimplEnv, (Id, Id, CoreExpr))
add_rules SimplEnv
env (Id
bndr, CoreExpr
rhs)
= do { (SimplEnv
env', Id
bndr') <- SimplEnv -> Id -> Id -> MaybeJoinCont -> SimplM (SimplEnv, Id)
addBndrRules SimplEnv
env Id
bndr (SimplEnv -> Id -> Id
lookupRecBndr SimplEnv
env Id
bndr) MaybeJoinCont
mb_cont
; (SimplEnv, (Id, Id, CoreExpr))
-> SimplM (SimplEnv, (Id, Id, CoreExpr))
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env', (Id
bndr, Id
bndr', CoreExpr
rhs)) }
go :: SimplEnv -> [(Id, Id, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env [] = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
go SimplEnv
env ((Id
old_bndr, Id
new_bndr, CoreExpr
rhs) : [(Id, Id, CoreExpr)]
pairs)
= do { (SimplFloats
float, SimplEnv
env1) <- SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env TopLevelFlag
top_lvl RecFlag
Recursive MaybeJoinCont
mb_cont
Id
old_bndr Id
new_bndr CoreExpr
rhs
; (SimplFloats
floats, SimplEnv
env2) <- SimplEnv -> [(Id, Id, CoreExpr)] -> SimplM (SimplFloats, SimplEnv)
go SimplEnv
env1 [(Id, Id, CoreExpr)]
pairs
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
float SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats, SimplEnv
env2) }
simplRecOrTopPair :: SimplEnv
-> TopLevelFlag -> RecFlag -> MaybeJoinCont
-> InId -> OutBndr -> InExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair :: SimplEnv
-> TopLevelFlag
-> RecFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
simplRecOrTopPair SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec MaybeJoinCont
mb_cont Id
old_bndr Id
new_bndr CoreExpr
rhs
| Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> Id -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
top_lvl Id
old_bndr CoreExpr
rhs SimplEnv
env
= {-#SCC "simplRecOrTopPair-pre-inline-uncond" #-}
[Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall {a}. [Char] -> a -> a
trace_bind [Char]
"pre-inline-uncond" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
do { Tick -> SimplM ()
tick (Id -> Tick
PreInlineUnconditionally Id
old_bndr)
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env' ) }
| Just SimplCont
cont <- MaybeJoinCont
mb_cont
= {-#SCC "simplRecOrTopPair-join" #-}
ASSERT( isNotTopLevel top_lvl && isJoinId new_bndr )
[Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall {a}. [Char] -> a -> a
trace_bind [Char]
"join" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
SimplEnv
-> SimplCont
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env SimplCont
cont Id
old_bndr Id
new_bndr CoreExpr
rhs SimplEnv
env
| Bool
otherwise
= {-#SCC "simplRecOrTopPair-normal" #-}
[Char]
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall {a}. [Char] -> a -> a
trace_bind [Char]
"normal" (SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv))
-> SimplM (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$
SimplEnv
-> TopLevelFlag
-> RecFlag
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec Id
old_bndr Id
new_bndr CoreExpr
rhs SimplEnv
env
where
dflags :: DynFlags
dflags = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
trace_bind :: [Char] -> a -> a
trace_bind [Char]
what a
thing_inside
| Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_verbose_core2core DynFlags
dflags)
= a
thing_inside
| Bool
otherwise
= DynFlags -> [Char] -> SDoc -> a -> a
TraceAction
traceAction DynFlags
dflags ([Char]
"SimplBind " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
what)
(Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
old_bndr) a
thing_inside
simplLazyBind :: SimplEnv
-> TopLevelFlag -> RecFlag
-> InId -> OutId
-> InExpr -> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind :: SimplEnv
-> TopLevelFlag
-> RecFlag
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env TopLevelFlag
top_lvl RecFlag
is_rec Id
bndr Id
bndr1 CoreExpr
rhs SimplEnv
rhs_se
= ASSERT( isId bndr )
ASSERT2( not (isJoinId bndr), ppr bndr )
do { let rhs_env :: SimplEnv
rhs_env = SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
([Id]
tvs, CoreExpr
body) = case CoreExpr -> ([Id], [Id], CoreExpr)
collectTyAndValBinders CoreExpr
rhs of
([Id]
tvs, [], CoreExpr
body)
| CoreExpr -> Bool
forall {b}. Expr b -> Bool
surely_not_lam CoreExpr
body -> ([Id]
tvs, CoreExpr
body)
([Id], [Id], CoreExpr)
_ -> ([], CoreExpr
rhs)
surely_not_lam :: Expr b -> Bool
surely_not_lam (Lam {}) = Bool
False
surely_not_lam (Tick Tickish Id
t Expr b
e)
| Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishFloatable Tickish Id
t) = Expr b -> Bool
surely_not_lam Expr b
e
surely_not_lam Expr b
_ = Bool
True
; (SimplEnv
body_env, [Id]
tvs') <- {-#SCC "simplBinders" #-} SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplBinders SimplEnv
rhs_env [Id]
tvs
; let rhs_cont :: SimplCont
rhs_cont = Kind -> SimplCont
mkRhsStop (SimplEnv -> Kind -> Kind
substTy SimplEnv
body_env (CoreExpr -> Kind
exprType CoreExpr
body))
; (SimplFloats
body_floats0, CoreExpr
body0) <- {-#SCC "simplExprF" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
body_env CoreExpr
body SimplCont
rhs_cont
; let (SimplFloats
body_floats1, CoreExpr
body1) = SimplFloats -> CoreExpr -> (SimplFloats, CoreExpr)
wrapJoinFloatsX SimplFloats
body_floats0 CoreExpr
body0
; (LetFloats
let_floats, Id
bndr2, CoreExpr
body2) <- {-#SCC "prepareBinding" #-}
SimplEnv
-> TopLevelFlag
-> Id
-> Id
-> CoreExpr
-> SimplM (LetFloats, Id, CoreExpr)
prepareBinding SimplEnv
env TopLevelFlag
top_lvl Id
bndr Id
bndr1 CoreExpr
body1
; let body_floats2 :: SimplFloats
body_floats2 = SimplFloats
body_floats1 SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
let_floats
; (SimplFloats
rhs_floats, CoreExpr
rhs')
<- if Bool -> Bool
not (TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> CoreExpr -> Bool
doFloatFromRhs TopLevelFlag
top_lvl RecFlag
is_rec Bool
False SimplFloats
body_floats2 CoreExpr
body2)
then
{-#SCC "simplLazyBind-no-floating" #-}
do { CoreExpr
rhs' <- SimplEnv -> [Id] -> CoreExpr -> SimplCont -> SimplM CoreExpr
mkLam SimplEnv
env [Id]
tvs' (SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
body_floats2 CoreExpr
body1) SimplCont
rhs_cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr
rhs') }
else if [Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
tvs then
{-#SCC "simplLazyBind-simple-floating" #-}
do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
body_floats2, CoreExpr
body2) }
else
{-#SCC "simplLazyBind-type-abstraction-first" #-}
do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
; ([InBind]
poly_binds, CoreExpr
body3) <- DynFlags
-> TopLevelFlag
-> [Id]
-> SimplFloats
-> CoreExpr
-> SimplM ([InBind], CoreExpr)
abstractFloats (SimplEnv -> DynFlags
seDynFlags SimplEnv
env) TopLevelFlag
top_lvl
[Id]
tvs' SimplFloats
body_floats2 CoreExpr
body2
; let floats :: SimplFloats
floats = (SimplFloats -> InBind -> SimplFloats)
-> SimplFloats -> [InBind] -> SimplFloats
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SimplFloats -> InBind -> SimplFloats
extendFloats (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env) [InBind]
poly_binds
; CoreExpr
rhs' <- SimplEnv -> [Id] -> CoreExpr -> SimplCont -> SimplM CoreExpr
mkLam SimplEnv
env [Id]
tvs' CoreExpr
body3 SimplCont
rhs_cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
rhs') }
; (SimplFloats
bind_float, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
rhs_floats)
TopLevelFlag
top_lvl MaybeJoinCont
forall a. Maybe a
Nothing Id
bndr Id
bndr2 CoreExpr
rhs'
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
rhs_floats SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
bind_float, SimplEnv
env2) }
simplJoinBind :: SimplEnv
-> SimplCont
-> InId -> OutId
-> InExpr -> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind :: SimplEnv
-> SimplCont
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env SimplCont
cont Id
old_bndr Id
new_bndr CoreExpr
rhs SimplEnv
rhs_se
= do { let rhs_env :: SimplEnv
rhs_env = SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
; CoreExpr
rhs' <- SimplEnv -> Id -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
rhs_env Id
old_bndr CoreExpr
rhs SimplCont
cont
; SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind SimplEnv
env TopLevelFlag
NotTopLevel (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont) Id
old_bndr Id
new_bndr CoreExpr
rhs' }
simplNonRecX :: SimplEnv
-> InId
-> OutExpr
-> SimplM (SimplFloats, SimplEnv)
simplNonRecX :: SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env Id
bndr CoreExpr
new_rhs
| ASSERT2( not (isJoinId bndr), ppr bndr )
Id -> Bool
isDeadBinder Id
bndr
= (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
| Coercion Coercion
co <- CoreExpr
new_rhs
= (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv -> Id -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env Id
bndr Coercion
co)
| Bool
otherwise
= do { (SimplEnv
env', Id
bndr') <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
env Id
bndr
; TopLevelFlag
-> SimplEnv
-> Bool
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeNonRecX TopLevelFlag
NotTopLevel SimplEnv
env' (Id -> Bool
isStrictId Id
bndr) Id
bndr Id
bndr' CoreExpr
new_rhs }
completeNonRecX :: TopLevelFlag -> SimplEnv
-> Bool
-> InId
-> OutId
-> OutExpr
-> SimplM (SimplFloats, SimplEnv)
completeNonRecX :: TopLevelFlag
-> SimplEnv
-> Bool
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeNonRecX TopLevelFlag
top_lvl SimplEnv
env Bool
is_strict Id
old_bndr Id
new_bndr CoreExpr
new_rhs
= ASSERT2( not (isJoinId new_bndr), ppr new_bndr )
do { (LetFloats
prepd_floats, Id
new_bndr, CoreExpr
new_rhs)
<- SimplEnv
-> TopLevelFlag
-> Id
-> Id
-> CoreExpr
-> SimplM (LetFloats, Id, CoreExpr)
prepareBinding SimplEnv
env TopLevelFlag
top_lvl Id
old_bndr Id
new_bndr CoreExpr
new_rhs
; let floats :: SimplFloats
floats = SimplEnv -> SimplFloats
emptyFloats SimplEnv
env SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
prepd_floats
; (SimplFloats
rhs_floats, CoreExpr
rhs2) <-
if TopLevelFlag -> RecFlag -> Bool -> SimplFloats -> CoreExpr -> Bool
doFloatFromRhs TopLevelFlag
NotTopLevel RecFlag
NonRecursive Bool
is_strict SimplFloats
floats CoreExpr
new_rhs
then
do { Tick -> SimplM ()
tick Tick
LetFloatFromLet
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
new_rhs) }
else
(SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
new_rhs)
; (SimplFloats
bind_float, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
rhs_floats)
TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing
Id
old_bndr Id
new_bndr CoreExpr
rhs2
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
rhs_floats SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
bind_float, SimplEnv
env2) }
prepareBinding :: SimplEnv -> TopLevelFlag
-> InId -> OutId -> OutExpr
-> SimplM (LetFloats, OutId, OutExpr)
prepareBinding :: SimplEnv
-> TopLevelFlag
-> Id
-> Id
-> CoreExpr
-> SimplM (LetFloats, Id, CoreExpr)
prepareBinding SimplEnv
env TopLevelFlag
top_lvl Id
old_bndr Id
bndr CoreExpr
rhs
| Cast CoreExpr
rhs1 Coercion
co <- CoreExpr
rhs
, Bool -> Bool
not (Unfolding -> Bool
isStableUnfolding (Id -> Unfolding
realIdUnfolding Id
old_bndr))
, Bool -> Bool
not (CoreExpr -> Bool
exprIsTrivial CoreExpr
rhs1)
, let ty1 :: Kind
ty1 = Coercion -> Kind
coercionLKind Coercion
co
, Bool -> Bool
not (HasDebugCallStack => Kind -> Bool
Kind -> Bool
isUnliftedType Kind
ty1)
= do { (LetFloats
floats, Id
new_id) <- SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, Id)
makeTrivialBinding (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
top_lvl
(Id -> FastString
forall a. NamedThing a => a -> FastString
getOccFS Id
bndr) IdInfo
worker_info CoreExpr
rhs1 Kind
ty1
; let bndr' :: Id
bndr' = Id
bndr Id -> InlinePragma -> Id
`setInlinePragma` InlinePragma -> InlinePragma
mkCastWrapperInlinePrag (Id -> InlinePragma
idInlinePragma Id
bndr)
; (LetFloats, Id, CoreExpr) -> SimplM (LetFloats, Id, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, Id
bndr', CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
new_id) Coercion
co) }
| Bool
otherwise
= do { (LetFloats
floats, CoreExpr
rhs') <- SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
top_lvl (Id -> FastString
forall a. NamedThing a => a -> FastString
getOccFS Id
bndr) CoreExpr
rhs
; (LetFloats, Id, CoreExpr) -> SimplM (LetFloats, Id, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, Id
bndr, CoreExpr
rhs') }
where
info :: IdInfo
info = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
bndr
worker_info :: IdInfo
worker_info = IdInfo
vanillaIdInfo IdInfo -> StrictSig -> IdInfo
`setStrictnessInfo` IdInfo -> StrictSig
strictnessInfo IdInfo
info
IdInfo -> CprSig -> IdInfo
`setCprInfo` IdInfo -> CprSig
cprInfo IdInfo
info
IdInfo -> Demand -> IdInfo
`setDemandInfo` IdInfo -> Demand
demandInfo IdInfo
info
IdInfo -> InlinePragma -> IdInfo
`setInlinePragInfo` IdInfo -> InlinePragma
inlinePragInfo IdInfo
info
IdInfo -> JoinArity -> IdInfo
`setArityInfo` IdInfo -> JoinArity
arityInfo IdInfo
info
mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma
mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma
mkCastWrapperInlinePrag (InlinePragma { inl_act :: InlinePragma -> Activation
inl_act = Activation
act, inl_rule :: InlinePragma -> RuleMatchInfo
inl_rule = RuleMatchInfo
rule_info })
= InlinePragma :: SourceText
-> InlineSpec
-> Maybe JoinArity
-> Activation
-> RuleMatchInfo
-> InlinePragma
InlinePragma { inl_src :: SourceText
inl_src = [Char] -> SourceText
SourceText [Char]
"{-# INLINE"
, inl_inline :: InlineSpec
inl_inline = InlineSpec
NoUserInline
, inl_sat :: Maybe JoinArity
inl_sat = Maybe JoinArity
forall a. Maybe a
Nothing
, inl_act :: Activation
inl_act = Activation
wrap_act
, inl_rule :: RuleMatchInfo
inl_rule = RuleMatchInfo
rule_info }
where
wrap_act :: Activation
wrap_act | Activation -> Bool
isNeverActive Activation
act = Activation
activateDuringFinal
| Bool
otherwise = Activation
act
prepareRhs :: SimplMode -> TopLevelFlag
-> FastString
-> OutExpr
-> SimplM (LetFloats, OutExpr)
prepareRhs :: SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs SimplMode
mode TopLevelFlag
top_lvl FastString
occ CoreExpr
rhs0
= do { (Bool
_is_exp, LetFloats
floats, CoreExpr
rhs1) <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
0 CoreExpr
rhs0
; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, CoreExpr
rhs1) }
where
go :: Int -> OutExpr -> SimplM (Bool, LetFloats, OutExpr)
go :: JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
n_val_args (Cast CoreExpr
rhs Coercion
co)
= do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
n_val_args CoreExpr
rhs
; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
rhs' Coercion
co) }
go JoinArity
n_val_args (App CoreExpr
fun (Type Kind
ty))
= do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
n_val_args CoreExpr
fun
; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
rhs' (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty)) }
go JoinArity
n_val_args (App CoreExpr
fun CoreExpr
arg)
= do { (Bool
is_exp, LetFloats
floats1, CoreExpr
fun') <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go (JoinArity
n_val_argsJoinArity -> JoinArity -> JoinArity
forall a. Num a => a -> a -> a
+JoinArity
1) CoreExpr
fun
; case Bool
is_exp of
Bool
False -> (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, LetFloats
emptyLetFloats, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun CoreExpr
arg)
Bool
True -> do { (LetFloats
floats2, CoreExpr
arg') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
topDmd FastString
occ CoreExpr
arg
; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, LetFloats
floats1 LetFloats -> LetFloats -> LetFloats
`addLetFlts` LetFloats
floats2, CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun' CoreExpr
arg') } }
go JoinArity
n_val_args (Var Id
fun)
= (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
emptyLetFloats, Id -> CoreExpr
forall b. Id -> Expr b
Var Id
fun)
where
is_exp :: Bool
is_exp = CheapAppFun
isExpandableApp Id
fun JoinArity
n_val_args
go JoinArity
n_val_args (Tick Tickish Id
t CoreExpr
rhs)
| Tickish Id -> TickishScoping
forall id. Tickish id -> TickishScoping
tickishScoped Tickish Id
t TickishScoping -> TickishScoping -> Bool
forall a. Eq a => a -> a -> Bool
== TickishScoping
NoScope
= do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
n_val_args CoreExpr
rhs
; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats, Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t CoreExpr
rhs') }
| (Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
t) Bool -> Bool -> Bool
|| Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCanSplit Tickish Id
t)
= do { (Bool
is_exp, LetFloats
floats, CoreExpr
rhs') <- JoinArity -> CoreExpr -> SimplM (Bool, LetFloats, CoreExpr)
go JoinArity
n_val_args CoreExpr
rhs
; let tickIt :: (a, CoreExpr) -> (a, CoreExpr)
tickIt (a
id, CoreExpr
expr) = (a
id, Tickish Id -> CoreExpr -> CoreExpr
mkTick (Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoCount Tickish Id
t) CoreExpr
expr)
floats' :: LetFloats
floats' = LetFloats -> ((Id, CoreExpr) -> (Id, CoreExpr)) -> LetFloats
mapLetFloats LetFloats
floats (Id, CoreExpr) -> (Id, CoreExpr)
forall {a}. (a, CoreExpr) -> (a, CoreExpr)
tickIt
; (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
is_exp, LetFloats
floats', Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
t CoreExpr
rhs') }
go JoinArity
_ CoreExpr
other
= (Bool, LetFloats, CoreExpr) -> SimplM (Bool, LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, LetFloats
emptyLetFloats, CoreExpr
other)
makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg SimplMode
mode arg :: ArgSpec
arg@(ValArg { as_arg :: ArgSpec -> CoreExpr
as_arg = CoreExpr
e, as_dmd :: ArgSpec -> Demand
as_dmd = Demand
dmd })
= do { (LetFloats
floats, CoreExpr
e') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
NotTopLevel Demand
dmd ([Char] -> FastString
fsLit [Char]
"arg") CoreExpr
e
; (LetFloats, ArgSpec) -> SimplM (LetFloats, ArgSpec)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, ArgSpec
arg { as_arg :: CoreExpr
as_arg = CoreExpr
e' }) }
makeTrivialArg SimplMode
_ ArgSpec
arg
= (LetFloats, ArgSpec) -> SimplM (LetFloats, ArgSpec)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
emptyLetFloats, ArgSpec
arg)
makeTrivial :: SimplMode -> TopLevelFlag -> Demand
-> FastString
-> OutExpr
-> SimplM (LetFloats, OutExpr)
makeTrivial :: SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
dmd FastString
occ_fs CoreExpr
expr
| CoreExpr -> Bool
exprIsTrivial CoreExpr
expr
Bool -> Bool -> Bool
|| Bool -> Bool
not (TopLevelFlag -> CoreExpr -> Kind -> Bool
bindingOk TopLevelFlag
top_lvl CoreExpr
expr Kind
expr_ty)
= (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
emptyLetFloats, CoreExpr
expr)
| Cast CoreExpr
expr' Coercion
co <- CoreExpr
expr
= do { (LetFloats
floats, CoreExpr
triv_expr) <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial SimplMode
mode TopLevelFlag
top_lvl Demand
dmd FastString
occ_fs CoreExpr
expr'
; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
triv_expr Coercion
co) }
| Bool
otherwise
= do { (LetFloats
floats, Id
new_id) <- SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, Id)
makeTrivialBinding SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs
IdInfo
id_info CoreExpr
expr Kind
expr_ty
; (LetFloats, CoreExpr) -> SimplM (LetFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (LetFloats
floats, Id -> CoreExpr
forall b. Id -> Expr b
Var Id
new_id) }
where
id_info :: IdInfo
id_info = IdInfo
vanillaIdInfo IdInfo -> Demand -> IdInfo
`setDemandInfo` Demand
dmd
expr_ty :: Kind
expr_ty = CoreExpr -> Kind
exprType CoreExpr
expr
makeTrivialBinding :: SimplMode -> TopLevelFlag
-> FastString
-> IdInfo
-> OutExpr
-> OutType
-> SimplM (LetFloats, OutId)
makeTrivialBinding :: SimplMode
-> TopLevelFlag
-> FastString
-> IdInfo
-> CoreExpr
-> Kind
-> SimplM (LetFloats, Id)
makeTrivialBinding SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs IdInfo
info CoreExpr
expr Kind
expr_ty
= do { (LetFloats
floats, CoreExpr
expr1) <- SimplMode
-> TopLevelFlag
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
prepareRhs SimplMode
mode TopLevelFlag
top_lvl FastString
occ_fs CoreExpr
expr
; Unique
uniq <- SimplM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
; let name :: Name
name = Unique -> FastString -> Name
mkSystemVarName Unique
uniq FastString
occ_fs
var :: Id
var = HasDebugCallStack => Name -> Kind -> Kind -> IdInfo -> Id
Name -> Kind -> Kind -> IdInfo -> Id
mkLocalIdWithInfo Name
name Kind
Many Kind
expr_ty IdInfo
info
; (ArityType
arity_type, CoreExpr
expr2) <- SimplMode -> Id -> CoreExpr -> SimplM (ArityType, CoreExpr)
tryEtaExpandRhs SimplMode
mode Id
var CoreExpr
expr1
; Unfolding
unf <- DynFlags
-> TopLevelFlag
-> UnfoldingSource
-> Id
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding (SimplMode -> DynFlags
sm_dflags SimplMode
mode) TopLevelFlag
top_lvl UnfoldingSource
InlineRhs Id
var CoreExpr
expr2
; let final_id :: Id
final_id = Id -> ArityType -> Unfolding -> Id
addLetBndrInfo Id
var ArityType
arity_type Unfolding
unf
bind :: InBind
bind = Id -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec Id
final_id CoreExpr
expr2
; (LetFloats, Id) -> SimplM (LetFloats, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return ( LetFloats
floats LetFloats -> LetFloats -> LetFloats
`addLetFlts` InBind -> LetFloats
unitLetFloat InBind
bind, Id
final_id ) }
bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool
bindingOk :: TopLevelFlag -> CoreExpr -> Kind -> Bool
bindingOk TopLevelFlag
top_lvl CoreExpr
expr Kind
expr_ty
| TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl = CoreExpr -> Kind -> Bool
exprIsTopLevelBindable CoreExpr
expr Kind
expr_ty
| Bool
otherwise = Bool
True
completeBind :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> InId
-> OutId -> OutExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Id
-> CoreExpr
-> SimplM (SimplFloats, SimplEnv)
completeBind SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont Id
old_bndr Id
new_bndr CoreExpr
new_rhs
| Id -> Bool
isCoVar Id
old_bndr
= case CoreExpr
new_rhs of
Coercion Coercion
co -> (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv -> Id -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env Id
old_bndr Coercion
co)
CoreExpr
_ -> (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> InBind -> (SimplFloats, SimplEnv)
mkFloatBind SimplEnv
env (Id -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec Id
new_bndr CoreExpr
new_rhs))
| Bool
otherwise
= ASSERT( isId new_bndr )
do { let old_info :: IdInfo
old_info = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
old_bndr
old_unf :: Unfolding
old_unf = IdInfo -> Unfolding
unfoldingInfo IdInfo
old_info
occ_info :: OccInfo
occ_info = IdInfo -> OccInfo
occInfo IdInfo
old_info
; (ArityType
new_arity, CoreExpr
final_rhs) <- SimplMode -> Id -> CoreExpr -> SimplM (ArityType, CoreExpr)
tryEtaExpandRhs (SimplEnv -> SimplMode
getMode SimplEnv
env) Id
new_bndr CoreExpr
new_rhs
; Unfolding
new_unfolding <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> CoreExpr
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplLetUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont Id
old_bndr
CoreExpr
final_rhs (Id -> Kind
idType Id
new_bndr) ArityType
new_arity Unfolding
old_unf
; let final_bndr :: Id
final_bndr = Id -> ArityType -> Unfolding -> Id
addLetBndrInfo Id
new_bndr ArityType
new_arity Unfolding
new_unfolding
; if SimplEnv -> TopLevelFlag -> Id -> OccInfo -> CoreExpr -> Bool
postInlineUnconditionally SimplEnv
env TopLevelFlag
top_lvl Id
final_bndr OccInfo
occ_info CoreExpr
final_rhs
then
do { Tick -> SimplM ()
tick (Id -> Tick
PostInlineUnconditionally Id
old_bndr)
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
, SimplEnv -> Id -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env Id
old_bndr (SimplSR -> SimplEnv) -> SimplSR -> SimplEnv
forall a b. (a -> b) -> a -> b
$
CoreExpr -> Maybe JoinArity -> SimplSR
DoneEx CoreExpr
final_rhs (Id -> Maybe JoinArity
isJoinId_maybe Id
new_bndr)) }
else
(SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> InBind -> (SimplFloats, SimplEnv)
mkFloatBind SimplEnv
env (Id -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec Id
final_bndr CoreExpr
final_rhs)) }
addLetBndrInfo :: OutId -> ArityType -> Unfolding -> OutId
addLetBndrInfo :: Id -> ArityType -> Unfolding -> Id
addLetBndrInfo Id
new_bndr ArityType
new_arity_type Unfolding
new_unf
= Id
new_bndr Id -> IdInfo -> Id
`setIdInfo` IdInfo
info5
where
new_arity :: JoinArity
new_arity = ArityType -> JoinArity
arityTypeArity ArityType
new_arity_type
is_bot :: Bool
is_bot = ArityType -> Bool
isBotArityType ArityType
new_arity_type
info1 :: IdInfo
info1 = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
new_bndr IdInfo -> JoinArity -> IdInfo
`setArityInfo` JoinArity
new_arity
info2 :: IdInfo
info2 = IdInfo
info1 IdInfo -> Unfolding -> IdInfo
`setUnfoldingInfo` Unfolding
new_unf
info3 :: IdInfo
info3 | Unfolding -> Bool
isEvaldUnfolding Unfolding
new_unf
Bool -> Bool -> Bool
|| (case IdInfo -> StrictSig
strictnessInfo IdInfo
info2 of
StrictSig DmdType
dmd_ty -> JoinArity
new_arity JoinArity -> JoinArity -> Bool
forall a. Ord a => a -> a -> Bool
< DmdType -> JoinArity
dmdTypeDepth DmdType
dmd_ty)
= IdInfo -> Maybe IdInfo
zapDemandInfo IdInfo
info2 Maybe IdInfo -> IdInfo -> IdInfo
forall a. Maybe a -> a -> a
`orElse` IdInfo
info2
| Bool
otherwise
= IdInfo
info2
info4 :: IdInfo
info4 | Bool
is_bot = IdInfo
info3 IdInfo -> StrictSig -> IdInfo
`setStrictnessInfo` StrictSig
bot_sig
IdInfo -> CprSig -> IdInfo
`setCprInfo` CprSig
bot_cpr
| Bool
otherwise = IdInfo
info3
bot_sig :: StrictSig
bot_sig = [Demand] -> Divergence -> StrictSig
mkClosedStrictSig (JoinArity -> Demand -> [Demand]
forall a. JoinArity -> a -> [a]
replicate JoinArity
new_arity Demand
topDmd) Divergence
botDiv
bot_cpr :: CprSig
bot_cpr = JoinArity -> CprResult -> CprSig
mkCprSig JoinArity
new_arity CprResult
botCpr
info5 :: IdInfo
info5 = IdInfo -> IdInfo
zapCallArityInfo IdInfo
info4
simplExpr :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env (Type Kind
ty)
= do { Kind
ty' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty') }
simplExpr SimplEnv
env CoreExpr
expr
= SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env CoreExpr
expr (Kind -> SimplCont
mkBoringStop Kind
expr_out_ty)
where
expr_out_ty :: OutType
expr_out_ty :: Kind
expr_out_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
expr)
simplExprC :: SimplEnv
-> InExpr
-> SimplCont
-> SimplM OutExpr
simplExprC :: SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env CoreExpr
expr SimplCont
cont
=
do { (SimplFloats
floats, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
cont
;
CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
expr') }
simplExprF :: SimplEnv
-> InExpr
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplExprF :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
e SimplCont
cont
=
SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF1 SimplEnv
env CoreExpr
e SimplCont
cont
simplExprF1 :: SimplEnv -> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplExprF1 :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF1 SimplEnv
_ (Type Kind
ty) SimplCont
cont
= [Char] -> SDoc -> SimplM (SimplFloats, CoreExpr)
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"simplExprF: type" (Kind -> SDoc
forall a. Outputable a => a -> SDoc
ppr Kind
ty SDoc -> SDoc -> SDoc
<+> [Char] -> SDoc
text[Char]
"cont: " SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont)
simplExprF1 SimplEnv
env (Var Id
v) SimplCont
cont = {-#SCC "simplIdF" #-} SimplEnv -> Id -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplIdF SimplEnv
env Id
v SimplCont
cont
simplExprF1 SimplEnv
env (Lit Literal
lit) SimplCont
cont = {-#SCC "rebuild" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit) SimplCont
cont
simplExprF1 SimplEnv
env (Tick Tickish Id
t CoreExpr
expr) SimplCont
cont = {-#SCC "simplTick" #-} SimplEnv
-> Tickish Id
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplTick SimplEnv
env Tickish Id
t CoreExpr
expr SimplCont
cont
simplExprF1 SimplEnv
env (Cast CoreExpr
body Coercion
co) SimplCont
cont = {-#SCC "simplCast" #-} SimplEnv
-> CoreExpr
-> Coercion
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplCast SimplEnv
env CoreExpr
body Coercion
co SimplCont
cont
simplExprF1 SimplEnv
env (Coercion Coercion
co) SimplCont
cont = {-#SCC "simplCoercionF" #-} SimplEnv -> Coercion -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplCoercionF SimplEnv
env Coercion
co SimplCont
cont
simplExprF1 SimplEnv
env (App CoreExpr
fun CoreExpr
arg) SimplCont
cont
= {-#SCC "simplExprF1-App" #-} case CoreExpr
arg of
Type Kind
ty -> do {
Kind
arg' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
; let hole' :: Kind
hole' = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
fun)
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
fun (SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplCont -> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$
ApplyToTy :: Kind -> Kind -> SimplCont -> SimplCont
ApplyToTy { sc_arg_ty :: Kind
sc_arg_ty = Kind
arg'
, sc_hole_ty :: Kind
sc_hole_ty = Kind
hole'
, sc_cont :: SimplCont
sc_cont = SimplCont
cont } }
CoreExpr
_ ->
SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
fun (SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplCont -> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$
ApplyToVal :: DupFlag -> Kind -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
ApplyToVal { sc_arg :: CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplEnv
sc_env = SimplEnv
env
, sc_hole_ty :: Kind
sc_hole_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env (CoreExpr -> Kind
exprType CoreExpr
fun)
, sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_cont :: SimplCont
sc_cont = SimplCont
cont }
simplExprF1 SimplEnv
env expr :: CoreExpr
expr@(Lam {}) SimplCont
cont
= {-#SCC "simplExprF1-Lam" #-}
SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [Id]
zapped_bndrs CoreExpr
body SimplCont
cont
where
([Id]
bndrs, CoreExpr
body) = CoreExpr -> ([Id], CoreExpr)
forall b. Expr b -> ([b], Expr b)
collectBinders CoreExpr
expr
zapped_bndrs :: [Id]
zapped_bndrs | Bool
need_to_zap = (Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Id
zap [Id]
bndrs
| Bool
otherwise = [Id]
bndrs
need_to_zap :: Bool
need_to_zap = (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Id -> Bool
zappable_bndr (JoinArity -> [Id] -> [Id]
forall a. JoinArity -> [a] -> [a]
drop JoinArity
n_args [Id]
bndrs)
n_args :: JoinArity
n_args = SimplCont -> JoinArity
countArgs SimplCont
cont
zappable_bndr :: Id -> Bool
zappable_bndr Id
b = Id -> Bool
isId Id
b Bool -> Bool -> Bool
&& Bool -> Bool
not (Id -> Bool
isOneShotBndr Id
b)
zap :: Id -> Id
zap Id
b | Id -> Bool
isTyVar Id
b = Id
b
| Bool
otherwise = Id -> Id
zapLamIdInfo Id
b
simplExprF1 SimplEnv
env (Case CoreExpr
scrut Id
bndr Kind
_ [Alt Id]
alts) SimplCont
cont
= {-#SCC "simplExprF1-Case" #-}
SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
scrut (Select :: DupFlag -> Id -> [Alt Id] -> SimplEnv -> SimplCont -> SimplCont
Select { sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_bndr :: Id
sc_bndr = Id
bndr
, sc_alts :: [Alt Id]
sc_alts = [Alt Id]
alts
, sc_env :: SimplEnv
sc_env = SimplEnv
env, sc_cont :: SimplCont
sc_cont = SimplCont
cont })
simplExprF1 SimplEnv
env (Let (Rec [(Id, CoreExpr)]
pairs) CoreExpr
body) SimplCont
cont
| Just [(Id, CoreExpr)]
pairs' <- [(Id, CoreExpr)] -> Maybe [(Id, CoreExpr)]
joinPointBindings_maybe [(Id, CoreExpr)]
pairs
= {-#SCC "simplRecJoinPoin" #-} SimplEnv
-> [(Id, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecJoinPoint SimplEnv
env [(Id, CoreExpr)]
pairs' CoreExpr
body SimplCont
cont
| Bool
otherwise
= {-#SCC "simplRecE" #-} SimplEnv
-> [(Id, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecE SimplEnv
env [(Id, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
simplExprF1 SimplEnv
env (Let (NonRec Id
bndr CoreExpr
rhs) CoreExpr
body) SimplCont
cont
| Type Kind
ty <- CoreExpr
rhs
= {-#SCC "simplExprF1-NonRecLet-Type" #-}
ASSERT( isTyVar bndr )
do { Kind
ty' <- SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv -> Id -> Kind -> SimplEnv
extendTvSubst SimplEnv
env Id
bndr Kind
ty') CoreExpr
body SimplCont
cont }
| Just (Id
bndr', CoreExpr
rhs') <- Id -> CoreExpr -> Maybe (Id, CoreExpr)
joinPointBinding_maybe Id
bndr CoreExpr
rhs
= {-#SCC "simplNonRecJoinPoint" #-} SimplEnv
-> Id
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecJoinPoint SimplEnv
env Id
bndr' CoreExpr
rhs' CoreExpr
body SimplCont
cont
| Bool
otherwise
= {-#SCC "simplNonRecE" #-} SimplEnv
-> Id
-> (CoreExpr, SimplEnv)
-> ([Id], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env Id
bndr (CoreExpr
rhs, SimplEnv
env) ([], CoreExpr
body) SimplCont
cont
simplJoinRhs :: SimplEnv -> InId -> InExpr -> SimplCont
-> SimplM OutExpr
simplJoinRhs :: SimplEnv -> Id -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
env Id
bndr CoreExpr
expr SimplCont
cont
| Just JoinArity
arity <- Id -> Maybe JoinArity
isJoinId_maybe Id
bndr
= do { let ([Id]
join_bndrs, CoreExpr
join_body) = JoinArity -> CoreExpr -> ([Id], CoreExpr)
forall b. JoinArity -> Expr b -> ([b], Expr b)
collectNBinders JoinArity
arity CoreExpr
expr
mult :: Kind
mult = SimplCont -> Kind
contHoleScaling SimplCont
cont
; (SimplEnv
env', [Id]
join_bndrs') <- SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplLamBndrs SimplEnv
env ((Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Kind -> Id -> Id
scaleVarBy Kind
mult) [Id]
join_bndrs)
; CoreExpr
join_body' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
join_body SimplCont
cont
; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> SimplM CoreExpr) -> CoreExpr -> SimplM CoreExpr
forall a b. (a -> b) -> a -> b
$ [Id] -> CoreExpr -> CoreExpr
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
join_bndrs' CoreExpr
join_body' }
| Bool
otherwise
= [Char] -> SDoc -> SimplM CoreExpr
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"simplJoinRhs" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
bndr)
simplType :: SimplEnv -> InType -> SimplM OutType
simplType :: SimplEnv -> Kind -> SimplM Kind
simplType SimplEnv
env Kind
ty
=
Kind -> ()
seqType Kind
new_ty () -> SimplM Kind -> SimplM Kind
`seq` Kind -> SimplM Kind
forall (m :: * -> *) a. Monad m => a -> m a
return Kind
new_ty
where
new_ty :: Kind
new_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env Kind
ty
simplCoercionF :: SimplEnv -> InCoercion -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplCoercionF :: SimplEnv -> Coercion -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplCoercionF SimplEnv
env Coercion
co SimplCont
cont
= do { Coercion
co' <- SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion Coercion
co') SimplCont
cont }
simplCoercion :: SimplEnv -> InCoercion -> SimplM OutCoercion
simplCoercion :: SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co
= do { DynFlags
dflags <- SimplM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let opt_co :: Coercion
opt_co = DynFlags -> TCvSubst -> Coercion -> Coercion
optCoercion DynFlags
dflags (SimplEnv -> TCvSubst
getTCvSubst SimplEnv
env) Coercion
co
; Coercion -> ()
seqCo Coercion
opt_co () -> SimplM Coercion -> SimplM Coercion
`seq` Coercion -> SimplM Coercion
forall (m :: * -> *) a. Monad m => a -> m a
return Coercion
opt_co }
simplTick :: SimplEnv -> Tickish Id -> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplTick :: SimplEnv
-> Tickish Id
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplTick SimplEnv
env Tickish Id
tickish CoreExpr
expr SimplCont
cont
| Tickish Id
tickish Tickish Id -> TickishScoping -> Bool
forall id. Tickish id -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
SoftScope
= do { (SimplFloats
floats, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
tickish CoreExpr
expr')
}
| Select {} <- SimplCont
cont, Just CoreExpr
expr' <- Maybe CoreExpr
push_tick_inside
= SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr' SimplCont
cont
| Bool
otherwise
= SimplM (SimplFloats, CoreExpr)
no_floating_past_tick
where
push_tick_inside :: Maybe CoreExpr
push_tick_inside =
case CoreExpr
expr0 of
Case CoreExpr
scrut Id
bndr Kind
ty [Alt Id]
alts
-> CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreExpr -> Maybe CoreExpr) -> CoreExpr -> Maybe CoreExpr
forall a b. (a -> b) -> a -> b
$ CoreExpr -> Id -> Kind -> [Alt Id] -> CoreExpr
forall b. Expr b -> b -> Kind -> [Alt b] -> Expr b
Case (CoreExpr -> CoreExpr
tickScrut CoreExpr
scrut) Id
bndr Kind
ty ((Alt Id -> Alt Id) -> [Alt Id] -> [Alt Id]
forall a b. (a -> b) -> [a] -> [b]
map Alt Id -> Alt Id
forall {a} {b}. (a, b, CoreExpr) -> (a, b, CoreExpr)
tickAlt [Alt Id]
alts)
CoreExpr
_other -> Maybe CoreExpr
forall a. Maybe a
Nothing
where ([Tickish Id]
ticks, CoreExpr
expr0) = (Tickish Id -> Bool) -> CoreExpr -> ([Tickish Id], CoreExpr)
forall b. (Tickish Id -> Bool) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop Tickish Id -> Bool
forall id. Tickish id -> Bool
movable (Tickish Id -> CoreExpr -> CoreExpr
forall b. Tickish Id -> Expr b -> Expr b
Tick Tickish Id
tickish CoreExpr
expr)
movable :: Tickish id -> Bool
movable Tickish id
t = Bool -> Bool
not (Tickish id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish id
t) Bool -> Bool -> Bool
||
Tickish id
t Tickish id -> TickishScoping -> Bool
forall id. Tickish id -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
NoScope Bool -> Bool -> Bool
||
Tickish id -> Bool
forall id. Tickish id -> Bool
tickishCanSplit Tickish id
t
tickScrut :: CoreExpr -> CoreExpr
tickScrut CoreExpr
e = (Tickish Id -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Id] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> CoreExpr -> CoreExpr
mkTick CoreExpr
e [Tickish Id]
ticks
tickAlt :: (a, b, CoreExpr) -> (a, b, CoreExpr)
tickAlt (a
c,b
bs,CoreExpr
e) = (a
c,b
bs, (Tickish Id -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Id] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> CoreExpr -> CoreExpr
mkTick CoreExpr
e [Tickish Id]
ts_scope)
ts_scope :: [Tickish Id]
ts_scope = (Tickish Id -> Tickish Id) -> [Tickish Id] -> [Tickish Id]
forall a b. (a -> b) -> [a] -> [b]
map Tickish Id -> Tickish Id
forall id. Tickish id -> Tickish id
mkNoCount ([Tickish Id] -> [Tickish Id]) -> [Tickish Id] -> [Tickish Id]
forall a b. (a -> b) -> a -> b
$
(Tickish Id -> Bool) -> [Tickish Id] -> [Tickish Id]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Tickish Id -> Bool) -> Tickish Id -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tickish Id -> TickishScoping -> Bool
forall id. Tickish id -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
NoScope)) [Tickish Id]
ticks
no_floating_past_tick :: SimplM (SimplFloats, CoreExpr)
no_floating_past_tick =
do { let (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
cont
; (SimplFloats
floats, CoreExpr
expr1) <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
expr SimplCont
inc
; let expr2 :: CoreExpr
expr2 = SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
expr1
tickish' :: Tickish Id
tickish' = SimplEnv -> Tickish Id -> Tickish Id
simplTickish SimplEnv
env Tickish Id
tickish
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
tickish' CoreExpr
expr2) SimplCont
outc
}
simplTickish :: SimplEnv -> Tickish Id -> Tickish Id
simplTickish SimplEnv
env Tickish Id
tickish
| Breakpoint JoinArity
n [Id]
ids <- Tickish Id
tickish
= JoinArity -> [Id] -> Tickish Id
forall id. JoinArity -> [id] -> Tickish id
Breakpoint JoinArity
n ((Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (SimplSR -> Id
getDoneId (SimplSR -> Id) -> (Id -> SimplSR) -> Id -> Id
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimplEnv -> Id -> SimplSR
substId SimplEnv
env) [Id]
ids)
| Bool
otherwise = Tickish Id
tickish
splitCont :: SimplCont -> (SimplCont, SimplCont)
splitCont :: SimplCont -> (SimplCont, SimplCont)
splitCont cont :: SimplCont
cont@(ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail }) = (SimplCont
cont { sc_cont :: SimplCont
sc_cont = SimplCont
inc }, SimplCont
outc)
where (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
tail
splitCont (CastIt Coercion
co SimplCont
c) = (Coercion -> SimplCont -> SimplCont
CastIt Coercion
co SimplCont
inc, SimplCont
outc)
where (SimplCont
inc,SimplCont
outc) = SimplCont -> (SimplCont, SimplCont)
splitCont SimplCont
c
splitCont SimplCont
other = (Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
other), SimplCont
other)
getDoneId :: SimplSR -> Id
getDoneId (DoneId Id
id) = Id
id
getDoneId (DoneEx CoreExpr
e Maybe JoinArity
_) = HasDebugCallStack => CoreExpr -> Id
CoreExpr -> Id
getIdFromTrivialExpr CoreExpr
e
getDoneId SimplSR
other = [Char] -> SDoc -> Id
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"getDoneId" (SimplSR -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplSR
other)
rebuild :: SimplEnv -> OutExpr -> SimplCont -> SimplM (SimplFloats, OutExpr)
rebuild :: SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env CoreExpr
expr SimplCont
cont
= case SimplCont
cont of
Stop {} -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr
expr)
TickIt Tickish Id
t SimplCont
cont -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
expr) SimplCont
cont
CastIt Coercion
co SimplCont
cont -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
expr Coercion
co) SimplCont
cont
Select { sc_bndr :: SimplCont -> Id
sc_bndr = Id
bndr, sc_alts :: SimplCont -> [Alt Id]
sc_alts = [Alt Id]
alts, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }
-> SimplEnv
-> CoreExpr
-> Id
-> [Alt Id]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
rebuildCase (SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
expr Id
bndr [Alt Id]
alts SimplCont
cont
StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_fun_ty :: SimplCont -> Kind
sc_fun_ty = Kind
fun_ty }
-> SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun CoreExpr
expr Kind
fun_ty ) SimplCont
cont
StrictBind { sc_bndr :: SimplCont -> Id
sc_bndr = Id
b, sc_bndrs :: SimplCont -> [Id]
sc_bndrs = [Id]
bs, sc_body :: SimplCont -> CoreExpr
sc_body = CoreExpr
body
, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont }
-> do { (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX (SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) Id
b CoreExpr
expr
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [Id]
bs CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont}
-> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
expr (Kind -> CoreExpr
forall b. Kind -> Expr b
Type Kind
ty)) SimplCont
cont
ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup_flag, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont}
-> do { (DupFlag
_, SimplEnv
_, CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup_flag SimplEnv
se CoreExpr
arg
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
expr CoreExpr
arg') SimplCont
cont }
simplCast :: SimplEnv -> InExpr -> Coercion -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplCast :: SimplEnv
-> CoreExpr
-> Coercion
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplCast SimplEnv
env CoreExpr
body Coercion
co0 SimplCont
cont0
= do { Coercion
co1 <- {-#SCC "simplCast-simplCoercion" #-} SimplEnv -> Coercion -> SimplM Coercion
simplCoercion SimplEnv
env Coercion
co0
; SimplCont
cont1 <- {-#SCC "simplCast-addCoerce" #-}
if Coercion -> Bool
isReflCo Coercion
co1
then SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont0
else Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co1 SimplCont
cont0
; {-#SCC "simplCast-simplExprF" #-} SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
body SimplCont
cont1 }
where
addCoerceM :: MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM :: MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
MRefl SimplCont
cont = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont
addCoerceM (MCo Coercion
co) SimplCont
cont = Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co SimplCont
cont
addCoerce :: OutCoercion -> SimplCont -> SimplM SimplCont
addCoerce :: Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co1 (CastIt Coercion
co2 SimplCont
cont)
| Coercion -> Bool
isReflexiveCo Coercion
co' = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont
| Bool
otherwise = Coercion -> SimplCont -> SimplM SimplCont
addCoerce Coercion
co' SimplCont
cont
where
co' :: Coercion
co' = Coercion -> Coercion -> Coercion
mkTransCo Coercion
co1 Coercion
co2
addCoerce Coercion
co (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail })
| Just (Kind
arg_ty', MOutCoercion
m_co') <- Coercion -> Kind -> Maybe (Kind, MOutCoercion)
pushCoTyArg Coercion
co Kind
arg_ty
= {-#SCC "addCoerce-pushCoTyArg" #-}
do { SimplCont
tail' <- MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
m_co' SimplCont
tail
; SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (ApplyToTy :: Kind -> Kind -> SimplCont -> SimplCont
ApplyToTy { sc_arg_ty :: Kind
sc_arg_ty = Kind
arg_ty'
, sc_cont :: SimplCont
sc_cont = SimplCont
tail'
, sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co }) }
addCoerce Coercion
co cont :: SimplCont
cont@(ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
tail })
| Just (Coercion
co1, MOutCoercion
m_co2) <- Coercion -> Maybe (Coercion, MOutCoercion)
pushCoValArg Coercion
co
, let new_ty :: Kind
new_ty = Coercion -> Kind
coercionRKind Coercion
co1
, Bool -> Bool
not (Kind -> Bool
isTypeLevPoly Kind
new_ty)
= {-#SCC "addCoerce-pushCoValArg" #-}
do { SimplCont
tail' <- MOutCoercion -> SimplCont -> SimplM SimplCont
addCoerceM MOutCoercion
m_co2 SimplCont
tail
; if Coercion -> Bool
isReflCo Coercion
co1
then SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplCont
cont { sc_cont :: SimplCont
sc_cont = SimplCont
tail'
, sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co })
else do
{ (DupFlag
dup', SimplEnv
arg_se', CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup SimplEnv
arg_se CoreExpr
arg
; SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (ApplyToVal :: DupFlag -> Kind -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
ApplyToVal { sc_arg :: CoreExpr
sc_arg = CoreExpr -> Coercion -> CoreExpr
mkCast CoreExpr
arg' Coercion
co1
, sc_env :: SimplEnv
sc_env = SimplEnv
arg_se'
, sc_dup :: DupFlag
sc_dup = DupFlag
dup'
, sc_cont :: SimplCont
sc_cont = SimplCont
tail'
, sc_hole_ty :: Kind
sc_hole_ty = Coercion -> Kind
coercionLKind Coercion
co }) } }
addCoerce Coercion
co SimplCont
cont
| Coercion -> Bool
isReflexiveCo Coercion
co = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return SimplCont
cont
| Bool
otherwise = SimplCont -> SimplM SimplCont
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> SimplCont -> SimplCont
CastIt Coercion
co SimplCont
cont)
simplArg :: SimplEnv -> DupFlag -> StaticEnv -> CoreExpr
-> SimplM (DupFlag, StaticEnv, OutExpr)
simplArg :: SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env DupFlag
dup_flag SimplEnv
arg_env CoreExpr
arg
| DupFlag -> Bool
isSimplified DupFlag
dup_flag
= (DupFlag, SimplEnv, CoreExpr)
-> SimplM (DupFlag, SimplEnv, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (DupFlag
dup_flag, SimplEnv
arg_env, CoreExpr
arg)
| Bool
otherwise
= do { CoreExpr
arg' <- SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr (SimplEnv
arg_env SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
arg
; (DupFlag, SimplEnv, CoreExpr)
-> SimplM (DupFlag, SimplEnv, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (DupFlag
Simplified, SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
arg_env, CoreExpr
arg') }
simplLam :: SimplEnv -> [InId] -> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplLam :: SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [] CoreExpr
body SimplCont
cont
= SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
body SimplCont
cont
simplLam SimplEnv
env (Id
bndr:[Id]
bndrs) CoreExpr
body (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= do { Tick -> SimplM ()
tick (Id -> Tick
BetaReduction Id
bndr)
; SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam (SimplEnv -> Id -> Kind -> SimplEnv
extendTvSubst SimplEnv
env Id
bndr Kind
arg_ty) [Id]
bndrs CoreExpr
body SimplCont
cont }
simplLam SimplEnv
env (Id
bndr:[Id]
bndrs) CoreExpr
body (ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup })
| DupFlag -> Bool
isSimplified DupFlag
dup
= do { Tick -> SimplM ()
tick (Id -> Tick
BetaReduction Id
bndr)
; (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env Id
zapped_bndr CoreExpr
arg
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [Id]
bndrs CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
| Bool
otherwise
= do { Tick -> SimplM ()
tick (Id -> Tick
BetaReduction Id
bndr)
; SimplEnv
-> Id
-> (CoreExpr, SimplEnv)
-> ([Id], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env Id
zapped_bndr (CoreExpr
arg, SimplEnv
arg_se) ([Id]
bndrs, CoreExpr
body) SimplCont
cont }
where
zapped_bndr :: Id
zapped_bndr
| Id -> Bool
isId Id
bndr = Id -> Id
zapStableUnfolding Id
bndr
| Bool
otherwise = Id
bndr
simplLam SimplEnv
env [Id]
bndrs CoreExpr
body (TickIt Tickish Id
tickish SimplCont
cont)
| Bool -> Bool
not (Tickish Id -> Bool
forall id. Tickish id -> Bool
tickishCounts Tickish Id
tickish)
= SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env [Id]
bndrs CoreExpr
body SimplCont
cont
simplLam SimplEnv
env [Id]
bndrs CoreExpr
body SimplCont
cont
= do { (SimplEnv
env', [Id]
bndrs') <- SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplLamBndrs SimplEnv
env [Id]
bndrs
; CoreExpr
body' <- SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env' CoreExpr
body
; CoreExpr
new_lam <- SimplEnv -> [Id] -> CoreExpr -> SimplCont -> SimplM CoreExpr
mkLam SimplEnv
env [Id]
bndrs' CoreExpr
body' SimplCont
cont
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env' CoreExpr
new_lam SimplCont
cont }
simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
simplLamBndr :: SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplLamBndr SimplEnv
env Id
bndr
| Id -> Bool
isId Id
bndr Bool -> Bool -> Bool
&& Unfolding -> Bool
hasCoreUnfolding Unfolding
old_unf
= do { (SimplEnv
env1, Id
bndr1) <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
env Id
bndr
; Unfolding
unf' <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env1 TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing Id
bndr
(Id -> Kind
idType Id
bndr1) (Id -> ArityType
idArityType Id
bndr1) Unfolding
old_unf
; let bndr2 :: Id
bndr2 = Id
bndr1 Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
unf'
; (SimplEnv, Id) -> SimplM (SimplEnv, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> Id -> SimplEnv
modifyInScope SimplEnv
env1 Id
bndr2, Id
bndr2) }
| Bool
otherwise
= SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
env Id
bndr
where
old_unf :: Unfolding
old_unf = Id -> Unfolding
idUnfolding Id
bndr
simplLamBndrs :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])
simplLamBndrs :: SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplLamBndrs SimplEnv
env [Id]
bndrs = (SimplEnv -> Id -> SimplM (SimplEnv, Id))
-> SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplLamBndr SimplEnv
env [Id]
bndrs
simplNonRecE :: SimplEnv
-> InId
-> (InExpr, SimplEnv)
-> ([InBndr], InExpr)
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplNonRecE :: SimplEnv
-> Id
-> (CoreExpr, SimplEnv)
-> ([Id], CoreExpr)
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecE SimplEnv
env Id
bndr (CoreExpr
rhs, SimplEnv
rhs_se) ([Id]
bndrs, CoreExpr
body) SimplCont
cont
| ASSERT( isId bndr && not (isJoinId bndr) ) True
, Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> Id -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
NotTopLevel Id
bndr CoreExpr
rhs SimplEnv
rhs_se
= do { Tick -> SimplM ()
tick (Id -> Tick
PreInlineUnconditionally Id
bndr)
;
SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env' [Id]
bndrs CoreExpr
body SimplCont
cont }
| Id -> Bool
isStrictId Id
bndr
, SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env)
= SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv
rhs_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
rhs
(StrictBind :: DupFlag
-> Id -> [Id] -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
StrictBind { sc_bndr :: Id
sc_bndr = Id
bndr, sc_bndrs :: [Id]
sc_bndrs = [Id]
bndrs, sc_body :: CoreExpr
sc_body = CoreExpr
body
, sc_env :: SimplEnv
sc_env = SimplEnv
env, sc_cont :: SimplCont
sc_cont = SimplCont
cont, sc_dup :: DupFlag
sc_dup = DupFlag
NoDup })
| Bool
otherwise
= ASSERT( not (isTyVar bndr) )
do { (SimplEnv
env1, Id
bndr1) <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplNonRecBndr SimplEnv
env Id
bndr
; (SimplEnv
env2, Id
bndr2) <- SimplEnv -> Id -> Id -> MaybeJoinCont -> SimplM (SimplEnv, Id)
addBndrRules SimplEnv
env1 Id
bndr Id
bndr1 MaybeJoinCont
forall a. Maybe a
Nothing
; (SimplFloats
floats1, SimplEnv
env3) <- SimplEnv
-> TopLevelFlag
-> RecFlag
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplLazyBind SimplEnv
env2 TopLevelFlag
NotTopLevel RecFlag
NonRecursive Id
bndr Id
bndr2 CoreExpr
rhs SimplEnv
rhs_se
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
env3 [Id]
bndrs CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
simplRecE :: SimplEnv
-> [(InId, InExpr)]
-> InExpr
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplRecE :: SimplEnv
-> [(Id, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecE SimplEnv
env [(Id, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
= do { let bndrs :: [Id]
bndrs = ((Id, CoreExpr) -> Id) -> [(Id, CoreExpr)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreExpr)]
pairs
; MASSERT(all (not . isJoinId) bndrs)
; SimplEnv
env1 <- SimplEnv -> [Id] -> SimplM SimplEnv
simplRecBndrs SimplEnv
env [Id]
bndrs
; (SimplFloats
floats1, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(Id, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env1 TopLevelFlag
NotTopLevel MaybeJoinCont
forall a. Maybe a
Nothing [(Id, CoreExpr)]
pairs
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
type MaybeJoinCont = Maybe SimplCont
simplNonRecJoinPoint :: SimplEnv -> InId -> InExpr
-> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplNonRecJoinPoint :: SimplEnv
-> Id
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplNonRecJoinPoint SimplEnv
env Id
bndr CoreExpr
rhs CoreExpr
body SimplCont
cont
| ASSERT( isJoinId bndr ) True
, Just SimplEnv
env' <- SimplEnv
-> TopLevelFlag -> Id -> CoreExpr -> SimplEnv -> Maybe SimplEnv
preInlineUnconditionally SimplEnv
env TopLevelFlag
NotTopLevel Id
bndr CoreExpr
rhs SimplEnv
env
= do { Tick -> SimplM ()
tick (Id -> Tick
PreInlineUnconditionally Id
bndr)
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
body SimplCont
cont }
| Bool
otherwise
= SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont ((SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr))
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$ \ SimplEnv
env SimplCont
cont ->
do {
; let mult :: Kind
mult = SimplCont -> Kind
contHoleScaling SimplCont
cont
res_ty :: Kind
res_ty = SimplCont -> Kind
contResultType SimplCont
cont
; (SimplEnv
env1, Id
bndr1) <- SimplEnv -> Id -> Kind -> Kind -> SimplM (SimplEnv, Id)
simplNonRecJoinBndr SimplEnv
env Id
bndr Kind
mult Kind
res_ty
; (SimplEnv
env2, Id
bndr2) <- SimplEnv -> Id -> Id -> MaybeJoinCont -> SimplM (SimplEnv, Id)
addBndrRules SimplEnv
env1 Id
bndr Id
bndr1 (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont)
; (SimplFloats
floats1, SimplEnv
env3) <- SimplEnv
-> SimplCont
-> Id
-> Id
-> CoreExpr
-> SimplEnv
-> SimplM (SimplFloats, SimplEnv)
simplJoinBind SimplEnv
env2 SimplCont
cont Id
bndr Id
bndr2 CoreExpr
rhs SimplEnv
env
; (SimplFloats
floats2, CoreExpr
body') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env3 CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
body') }
simplRecJoinPoint :: SimplEnv -> [(InId, InExpr)]
-> InExpr -> SimplCont
-> SimplM (SimplFloats, OutExpr)
simplRecJoinPoint :: SimplEnv
-> [(Id, CoreExpr)]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
simplRecJoinPoint SimplEnv
env [(Id, CoreExpr)]
pairs CoreExpr
body SimplCont
cont
= SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont ((SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr))
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
forall a b. (a -> b) -> a -> b
$ \ SimplEnv
env SimplCont
cont ->
do { let bndrs :: [Id]
bndrs = ((Id, CoreExpr) -> Id) -> [(Id, CoreExpr)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreExpr)]
pairs
mult :: Kind
mult = SimplCont -> Kind
contHoleScaling SimplCont
cont
res_ty :: Kind
res_ty = SimplCont -> Kind
contResultType SimplCont
cont
; SimplEnv
env1 <- SimplEnv -> [Id] -> Kind -> Kind -> SimplM SimplEnv
simplRecJoinBndrs SimplEnv
env [Id]
bndrs Kind
mult Kind
res_ty
; (SimplFloats
floats1, SimplEnv
env2) <- SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> [(Id, CoreExpr)]
-> SimplM (SimplFloats, SimplEnv)
simplRecBind SimplEnv
env1 TopLevelFlag
NotTopLevel (SimplCont -> MaybeJoinCont
forall a. a -> Maybe a
Just SimplCont
cont) [(Id, CoreExpr)]
pairs
; (SimplFloats
floats2, CoreExpr
body') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
body SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
body') }
wrapJoinCont :: SimplEnv -> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, OutExpr))
-> SimplM (SimplFloats, OutExpr)
wrapJoinCont :: SimplEnv
-> SimplCont
-> (SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr))
-> SimplM (SimplFloats, CoreExpr)
wrapJoinCont SimplEnv
env SimplCont
cont SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside
| SimplCont -> Bool
contIsStop SimplCont
cont
= SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside SimplEnv
env SimplCont
cont
| Bool -> Bool
not (SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env))
= do { (SimplFloats
floats1, CoreExpr
expr1) <- SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside SimplEnv
env (Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
cont))
; let (SimplFloats
floats2, CoreExpr
expr2) = SimplFloats -> CoreExpr -> (SimplFloats, CoreExpr)
wrapJoinFloatsX SimplFloats
floats1 CoreExpr
expr1
; (SimplFloats
floats3, CoreExpr
expr3) <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats2) CoreExpr
expr2 SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3, CoreExpr
expr3) }
| Bool
otherwise
= do { (SimplFloats
floats1, SimplCont
cont') <- SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
; (SimplFloats
floats2, CoreExpr
result) <- SimplEnv -> SimplCont -> SimplM (SimplFloats, CoreExpr)
thing_inside (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats1) SimplCont
cont'
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
result) }
trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont
trimJoinCont :: Id -> Maybe JoinArity -> SimplCont -> SimplCont
trimJoinCont Id
_ Maybe JoinArity
Nothing SimplCont
cont
= SimplCont
cont
trimJoinCont Id
var (Just JoinArity
arity) SimplCont
cont
= JoinArity -> SimplCont -> SimplCont
forall {a}. (Eq a, Num a) => a -> SimplCont -> SimplCont
trim JoinArity
arity SimplCont
cont
where
trim :: a -> SimplCont -> SimplCont
trim a
0 cont :: SimplCont
cont@(Stop {})
= SimplCont
cont
trim a
0 SimplCont
cont
= Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contResultType SimplCont
cont)
trim a
n cont :: SimplCont
cont@(ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= SimplCont
cont { sc_cont :: SimplCont
sc_cont = a -> SimplCont -> SimplCont
trim (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) SimplCont
k }
trim a
n cont :: SimplCont
cont@(ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k })
= SimplCont
cont { sc_cont :: SimplCont
sc_cont = a -> SimplCont -> SimplCont
trim (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) SimplCont
k }
trim a
_ SimplCont
cont
= [Char] -> SDoc -> SimplCont
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"completeCall" (SDoc -> SimplCont) -> SDoc -> SimplCont
forall a b. (a -> b) -> a -> b
$ Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
var SDoc -> SDoc -> SDoc
$$ SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont
simplVar :: SimplEnv -> InVar -> SimplM OutExpr
simplVar :: SimplEnv -> Id -> SimplM CoreExpr
simplVar SimplEnv
env Id
var
| Id -> Bool
isTyVar Id
var = CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Kind -> CoreExpr
forall b. Kind -> Expr b
Type (SimplEnv -> Id -> Kind
substTyVar SimplEnv
env Id
var))
| Id -> Bool
isCoVar Id
var = CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Coercion -> CoreExpr
forall b. Coercion -> Expr b
Coercion (SimplEnv -> Id -> Coercion
substCoVar SimplEnv
env Id
var))
| Bool
otherwise
= case SimplEnv -> Id -> SimplSR
substId SimplEnv
env Id
var of
ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids CoreExpr
e -> SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr (SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv SimplEnv
env TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids) CoreExpr
e
DoneId Id
var1 -> CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
var1)
DoneEx CoreExpr
e Maybe JoinArity
_ -> CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
e
simplIdF :: SimplEnv -> InId -> SimplCont -> SimplM (SimplFloats, OutExpr)
simplIdF :: SimplEnv -> Id -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplIdF SimplEnv
env Id
var SimplCont
cont
= case SimplEnv -> Id -> SimplSR
substId SimplEnv
env Id
var of
ContEx TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids CoreExpr
e -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
setSubstEnv SimplEnv
env TvSubstEnv
tvs CvSubstEnv
cvs SimplIdSubst
ids) CoreExpr
e SimplCont
cont
DoneId Id
var1 -> SimplEnv -> Id -> SimplCont -> SimplM (SimplFloats, CoreExpr)
completeCall SimplEnv
env Id
var1 (Id -> Maybe JoinArity -> SimplCont -> SimplCont
trimJoinCont Id
var (Id -> Maybe JoinArity
isJoinId_maybe Id
var1) SimplCont
cont)
DoneEx CoreExpr
e Maybe JoinArity
mb_join -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env) CoreExpr
e (Id -> Maybe JoinArity -> SimplCont -> SimplCont
trimJoinCont Id
var Maybe JoinArity
mb_join SimplCont
cont)
completeCall :: SimplEnv -> OutId -> SimplCont -> SimplM (SimplFloats, OutExpr)
completeCall :: SimplEnv -> Id -> SimplCont -> SimplM (SimplFloats, CoreExpr)
completeCall SimplEnv
env Id
var SimplCont
cont
| Just CoreExpr
expr <- DynFlags
-> Id -> Bool -> Bool -> [ArgSummary] -> CallCtxt -> Maybe CoreExpr
callSiteInline DynFlags
dflags Id
var Bool
active_unf
Bool
lone_variable [ArgSummary]
arg_infos CallCtxt
interesting_cont
= do { Tick -> SimplM ()
checkedTick (Id -> Tick
UnfoldingDone Id
var)
; CoreExpr -> SimplCont -> SimplM ()
forall {m :: * -> *} {a} {a}.
(MonadIO m, Outputable a, Outputable a) =>
a -> a -> m ()
dump_inline CoreExpr
expr SimplCont
cont
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env) CoreExpr
expr SimplCont
cont }
| Bool
otherwise
= do { RuleEnv
rule_base <- SimplM RuleEnv
getSimplRules
; let info :: ArgInfo
info = SimplEnv -> Id -> [CoreRule] -> JoinArity -> SimplCont -> ArgInfo
mkArgInfo SimplEnv
env Id
var (RuleEnv -> Id -> [CoreRule]
getRules RuleEnv
rule_base Id
var)
JoinArity
n_val_args SimplCont
call_cont
; SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env ArgInfo
info SimplCont
cont }
where
dflags :: DynFlags
dflags = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
(Bool
lone_variable, [ArgSummary]
arg_infos, SimplCont
call_cont) = SimplCont -> (Bool, [ArgSummary], SimplCont)
contArgs SimplCont
cont
n_val_args :: JoinArity
n_val_args = [ArgSummary] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [ArgSummary]
arg_infos
interesting_cont :: CallCtxt
interesting_cont = SimplEnv -> SimplCont -> CallCtxt
interestingCallContext SimplEnv
env SimplCont
call_cont
active_unf :: Bool
active_unf = SimplMode -> Id -> Bool
activeUnfolding (SimplEnv -> SimplMode
getMode SimplEnv
env) Id
var
log_inlining :: SDoc -> m ()
log_inlining SDoc
doc
= IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ DumpAction
dumpAction DynFlags
dflags
(PrintUnqualified -> PprStyle
mkDumpStyle PrintUnqualified
alwaysQualify)
(DumpFlag -> DumpOptions
dumpOptionsFromFlag DumpFlag
Opt_D_dump_inlinings)
[Char]
"" DumpFormat
FormatText SDoc
doc
dump_inline :: a -> a -> m ()
dump_inline a
unfolding a
cont
| Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_inlinings DynFlags
dflags) = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool -> Bool
not (DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_verbose_core2core DynFlags
dflags)
= Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Name -> Bool
isExternalName (Id -> Name
idName Id
var)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
SDoc -> m ()
forall {m :: * -> *}. MonadIO m => SDoc -> m ()
log_inlining (SDoc -> m ()) -> SDoc -> m ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
"Inlining done:", JoinArity -> SDoc -> SDoc
nest JoinArity
4 (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
var)]
| Bool
otherwise
= IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ SDoc -> IO ()
forall {m :: * -> *}. MonadIO m => SDoc -> m ()
log_inlining (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
"Inlining done: " SDoc -> SDoc -> SDoc
<> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
var,
JoinArity -> SDoc -> SDoc
nest JoinArity
4 ([SDoc] -> SDoc
vcat [[Char] -> SDoc
text [Char]
"Inlined fn: " SDoc -> SDoc -> SDoc
<+> JoinArity -> SDoc -> SDoc
nest JoinArity
2 (a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
unfolding),
[Char] -> SDoc
text [Char]
"Cont: " SDoc -> SDoc -> SDoc
<+> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
cont])]
rebuildCall :: SimplEnv
-> ArgInfo
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
rebuildCall :: SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> Id
ai_fun = Id
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args, ai_dmds :: ArgInfo -> [Demand]
ai_dmds = [] }) SimplCont
cont
| Bool -> Bool
not (SimplCont -> Bool
contIsTrivial SimplCont
cont)
= Kind -> ()
seqType Kind
cont_ty ()
-> SimplM (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
`seq`
(SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr -> Kind -> CoreExpr
castBottomExpr CoreExpr
res Kind
cont_ty)
where
res :: CoreExpr
res = Id -> [ArgSpec] -> CoreExpr
argInfoExpr Id
fun [ArgSpec]
rev_args
cont_ty :: Kind
cont_ty = SimplCont -> Kind
contResultType SimplCont
cont
rebuildCall SimplEnv
env info :: ArgInfo
info@(ArgInfo { ai_fun :: ArgInfo -> Id
ai_fun = Id
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args
, ai_rules :: ArgInfo -> FunRules
ai_rules = Just (JoinArity
nr_wanted, [CoreRule]
rules) }) SimplCont
cont
| JoinArity
nr_wanted JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
== JoinArity
0 Bool -> Bool -> Bool
|| Bool
no_more_args
, let info' :: ArgInfo
info' = ArgInfo
info { ai_rules :: FunRules
ai_rules = FunRules
forall a. Maybe a
Nothing }
=
do { Maybe (SimplEnv, CoreExpr, SimplCont)
mb_match <- SimplEnv
-> [CoreRule]
-> Id
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
env [CoreRule]
rules Id
fun ([ArgSpec] -> [ArgSpec]
forall a. [a] -> [a]
reverse [ArgSpec]
rev_args) SimplCont
cont
; case Maybe (SimplEnv, CoreExpr, SimplCont)
mb_match of
Just (SimplEnv
env', CoreExpr
rhs, SimplCont
cont') -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont'
Maybe (SimplEnv, CoreExpr, SimplCont)
Nothing -> SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env ArgInfo
info' SimplCont
cont }
where
no_more_args :: Bool
no_more_args = case SimplCont
cont of
ApplyToTy {} -> Bool
False
ApplyToVal {} -> Bool
False
SimplCont
_ -> Bool
True
rebuildCall SimplEnv
env ArgInfo
info (CastIt Coercion
co SimplCont
cont)
= SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> Coercion -> ArgInfo
addCastTo ArgInfo
info Coercion
co) SimplCont
cont
rebuildCall SimplEnv
env ArgInfo
info (ApplyToTy { sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
= SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> Kind -> Kind -> ArgInfo
addTyArgTo ArgInfo
info Kind
arg_ty Kind
hole_ty) SimplCont
cont
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> Id
ai_fun = Id
fun_id, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args })
(ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
fun_ty })
| Id
fun_id Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
runRWKey
, Bool -> Bool
not (SimplCont -> Bool
contIsStop SimplCont
cont)
, [ TyArg {}, TyArg {} ] <- [ArgSpec]
rev_args
= do { Id
s <- FastString -> Kind -> Kind -> SimplM Id
newId ([Char] -> FastString
fsLit [Char]
"s") Kind
Many Kind
realWorldStatePrimTy
; let (Kind
m,Kind
_,Kind
_) = Kind -> (Kind, Kind, Kind)
splitFunTy Kind
fun_ty
env' :: SimplEnv
env' = (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) SimplEnv -> [Id] -> SimplEnv
`addNewInScopeIds` [Id
s]
ty' :: Kind
ty' = SimplCont -> Kind
contResultType SimplCont
cont
cont' :: SimplCont
cont' = ApplyToVal :: DupFlag -> Kind -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
ApplyToVal { sc_dup :: DupFlag
sc_dup = DupFlag
Simplified, sc_arg :: CoreExpr
sc_arg = Id -> CoreExpr
forall b. Id -> Expr b
Var Id
s
, sc_env :: SimplEnv
sc_env = SimplEnv
env', sc_cont :: SimplCont
sc_cont = SimplCont
cont
, sc_hole_ty :: Kind
sc_hole_ty = Kind -> Kind -> Kind -> Kind
mkVisFunTy Kind
m Kind
realWorldStatePrimTy Kind
ty' }
; CoreExpr
body' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
arg SimplCont
cont'
; let arg' :: CoreExpr
arg' = Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
s CoreExpr
body'
rr' :: Kind
rr' = HasDebugCallStack => Kind -> Kind
Kind -> Kind
getRuntimeRep Kind
ty'
call' :: CoreExpr
call' = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
fun_id) [Kind -> CoreExpr
forall b. Kind -> Expr b
mkTyArg Kind
rr', Kind -> CoreExpr
forall b. Kind -> Expr b
mkTyArg Kind
ty', CoreExpr
arg']
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, CoreExpr
call') }
rebuildCall SimplEnv
env ArgInfo
fun_info
(ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
arg_se
, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup_flag, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
fun_ty
, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
| DupFlag -> Bool
isSimplified DupFlag
dup_flag
= SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun_info CoreExpr
arg Kind
fun_ty) SimplCont
cont
| ArgInfo -> Bool
isStrictArgInfo ArgInfo
fun_info
, SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env)
=
SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
arg
(StrictArg :: DupFlag -> ArgInfo -> Kind -> SimplCont -> SimplCont
StrictArg { sc_fun :: ArgInfo
sc_fun = ArgInfo
fun_info, sc_fun_ty :: Kind
sc_fun_ty = Kind
fun_ty
, sc_dup :: DupFlag
sc_dup = DupFlag
Simplified
, sc_cont :: SimplCont
sc_cont = SimplCont
cont })
| Bool
otherwise
= do { CoreExpr
arg' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC (SimplEnv
arg_se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env) CoreExpr
arg
(Kind -> CallCtxt -> SimplCont
mkLazyArgStop Kind
arg_ty (ArgInfo -> CallCtxt
lazyArgContext ArgInfo
fun_info))
; SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun_info CoreExpr
arg' Kind
fun_ty) SimplCont
cont }
where
arg_ty :: Kind
arg_ty = Kind -> Kind
funArgTy Kind
fun_ty
rebuildCall SimplEnv
env (ArgInfo { ai_fun :: ArgInfo -> Id
ai_fun = Id
fun, ai_args :: ArgInfo -> [ArgSpec]
ai_args = [ArgSpec]
rev_args }) SimplCont
cont
= SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env (Id -> [ArgSpec] -> CoreExpr
argInfoExpr Id
fun [ArgSpec]
rev_args) SimplCont
cont
tryRules :: SimplEnv -> [CoreRule]
-> Id -> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules :: SimplEnv
-> [CoreRule]
-> Id
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
env [CoreRule]
rules Id
fn [ArgSpec]
args SimplCont
call_cont
| [CoreRule] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
rules
= Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. Maybe a
Nothing
| Just (CoreRule
rule, CoreExpr
rule_rhs) <- RuleOpts
-> InScopeEnv
-> (Activation -> Bool)
-> Id
-> [CoreExpr]
-> [CoreRule]
-> Maybe (CoreRule, CoreExpr)
lookupRule RuleOpts
ropts (SimplEnv -> InScopeEnv
getUnfoldingInRuleMatch SimplEnv
env)
(SimplMode -> Activation -> Bool
activeRule (SimplEnv -> SimplMode
getMode SimplEnv
env)) Id
fn
([ArgSpec] -> [CoreExpr]
argInfoAppArgs [ArgSpec]
args) [CoreRule]
rules
= do { Tick -> SimplM ()
checkedTick (FastString -> Tick
RuleFired (CoreRule -> FastString
ruleName CoreRule
rule))
; let cont' :: SimplCont
cont' = SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont
pushSimplifiedArgs SimplEnv
zapped_env
(JoinArity -> [ArgSpec] -> [ArgSpec]
forall a. JoinArity -> [a] -> [a]
drop (CoreRule -> JoinArity
ruleArity CoreRule
rule) [ArgSpec]
args)
SimplCont
call_cont
occ_anald_rhs :: CoreExpr
occ_anald_rhs = CoreExpr -> CoreExpr
occurAnalyseExpr CoreExpr
rule_rhs
; CoreRule -> CoreExpr -> SimplM ()
forall {m :: * -> *} {b}.
(MonadIO m, OutputableBndr b) =>
CoreRule -> Expr b -> m ()
dump CoreRule
rule CoreExpr
rule_rhs
; Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return ((SimplEnv, CoreExpr, SimplCont)
-> Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. a -> Maybe a
Just (SimplEnv
zapped_env, CoreExpr
occ_anald_rhs, SimplCont
cont')) }
| Bool
otherwise
= do { SimplM ()
nodump
; Maybe (SimplEnv, CoreExpr, SimplCont)
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (SimplEnv, CoreExpr, SimplCont)
forall a. Maybe a
Nothing }
where
ropts :: RuleOpts
ropts = DynFlags -> RuleOpts
initRuleOpts DynFlags
dflags
dflags :: DynFlags
dflags = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
zapped_env :: SimplEnv
zapped_env = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env
printRuleModule :: CoreRule -> SDoc
printRuleModule CoreRule
rule
= SDoc -> SDoc
parens (SDoc -> (GenModule Unit -> SDoc) -> Maybe (GenModule Unit) -> SDoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([Char] -> SDoc
text [Char]
"BUILTIN")
(ModuleName -> SDoc
pprModuleName (ModuleName -> SDoc)
-> (GenModule Unit -> ModuleName) -> GenModule Unit -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenModule Unit -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName)
(CoreRule -> Maybe (GenModule Unit)
ruleModule CoreRule
rule))
dump :: CoreRule -> Expr b -> m ()
dump CoreRule
rule Expr b
rule_rhs
| DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_rewrites DynFlags
dflags
= DynFlags -> DumpFlag -> [Char] -> SDoc -> m ()
forall {m :: * -> *}.
MonadIO m =>
DynFlags -> DumpFlag -> [Char] -> SDoc -> m ()
log_rule DynFlags
dflags DumpFlag
Opt_D_dump_rule_rewrites [Char]
"Rule fired" (SDoc -> m ()) -> SDoc -> m ()
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
vcat
[ [Char] -> SDoc
text [Char]
"Rule:" SDoc -> SDoc -> SDoc
<+> FastString -> SDoc
ftext (CoreRule -> FastString
ruleName CoreRule
rule)
, [Char] -> SDoc
text [Char]
"Module:" SDoc -> SDoc -> SDoc
<+> CoreRule -> SDoc
printRuleModule CoreRule
rule
, [Char] -> SDoc
text [Char]
"Before:" SDoc -> SDoc -> SDoc
<+> SDoc -> JoinArity -> SDoc -> SDoc
hang (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
fn) JoinArity
2 ([SDoc] -> SDoc
sep ((ArgSpec -> SDoc) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgSpec -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ArgSpec]
args))
, [Char] -> SDoc
text [Char]
"After: " SDoc -> SDoc -> SDoc
<+> SDoc -> JoinArity -> SDoc -> SDoc
hang (Expr b -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr Expr b
rule_rhs) JoinArity
2
([SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (ArgSpec -> SDoc) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgSpec -> SDoc
forall a. Outputable a => a -> SDoc
ppr ([ArgSpec] -> [SDoc]) -> [ArgSpec] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ JoinArity -> [ArgSpec] -> [ArgSpec]
forall a. JoinArity -> [a] -> [a]
drop (CoreRule -> JoinArity
ruleArity CoreRule
rule) [ArgSpec]
args)
, [Char] -> SDoc
text [Char]
"Cont: " SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
call_cont ]
| DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_firings DynFlags
dflags
= DynFlags -> DumpFlag -> [Char] -> SDoc -> m ()
forall {m :: * -> *}.
MonadIO m =>
DynFlags -> DumpFlag -> [Char] -> SDoc -> m ()
log_rule DynFlags
dflags DumpFlag
Opt_D_dump_rule_firings [Char]
"Rule fired:" (SDoc -> m ()) -> SDoc -> m ()
forall a b. (a -> b) -> a -> b
$
FastString -> SDoc
ftext (CoreRule -> FastString
ruleName CoreRule
rule)
SDoc -> SDoc -> SDoc
<+> CoreRule -> SDoc
printRuleModule CoreRule
rule
| Bool
otherwise
= () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
nodump :: SimplM ()
nodump
| DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_rewrites DynFlags
dflags
= IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ do
DynFlags -> DumpOptions -> IO ()
touchDumpFile DynFlags
dflags (DumpFlag -> DumpOptions
dumpOptionsFromFlag DumpFlag
Opt_D_dump_rule_rewrites)
| DumpFlag -> DynFlags -> Bool
dopt DumpFlag
Opt_D_dump_rule_firings DynFlags
dflags
= IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ do
DynFlags -> DumpOptions -> IO ()
touchDumpFile DynFlags
dflags (DumpFlag -> DumpOptions
dumpOptionsFromFlag DumpFlag
Opt_D_dump_rule_firings)
| Bool
otherwise
= () -> SimplM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
log_rule :: DynFlags -> DumpFlag -> [Char] -> SDoc -> m ()
log_rule DynFlags
dflags DumpFlag
flag [Char]
hdr SDoc
details
= IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
let sty :: PprStyle
sty = PrintUnqualified -> PprStyle
mkDumpStyle PrintUnqualified
alwaysQualify
DumpAction
dumpAction DynFlags
dflags PprStyle
sty (DumpFlag -> DumpOptions
dumpOptionsFromFlag DumpFlag
flag) [Char]
"" DumpFormat
FormatText (SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
sep [[Char] -> SDoc
text [Char]
hdr, JoinArity -> SDoc -> SDoc
nest JoinArity
4 SDoc
details]
trySeqRules :: SimplEnv
-> OutExpr -> InExpr
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules :: SimplEnv
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules SimplEnv
in_env CoreExpr
scrut CoreExpr
rhs SimplCont
cont
= do { RuleEnv
rule_base <- SimplM RuleEnv
getSimplRules
; SimplEnv
-> [CoreRule]
-> Id
-> [ArgSpec]
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
tryRules SimplEnv
in_env (RuleEnv -> Id -> [CoreRule]
getRules RuleEnv
rule_base Id
seqId) Id
seqId [ArgSpec]
out_args SimplCont
rule_cont }
where
no_cast_scrut :: CoreExpr
no_cast_scrut = CoreExpr -> CoreExpr
forall {b}. Expr b -> Expr b
drop_casts CoreExpr
scrut
scrut_ty :: Kind
scrut_ty = CoreExpr -> Kind
exprType CoreExpr
no_cast_scrut
seq_id_ty :: Kind
seq_id_ty = Id -> Kind
idType Id
seqId
res1_ty :: Kind
res1_ty = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
seq_id_ty Kind
rhs_rep
res2_ty :: Kind
res2_ty = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
res1_ty Kind
scrut_ty
res3_ty :: Kind
res3_ty = HasDebugCallStack => Kind -> Kind -> Kind
Kind -> Kind -> Kind
piResultTy Kind
res2_ty Kind
rhs_ty
res4_ty :: Kind
res4_ty = Kind -> Kind
funResultTy Kind
res3_ty
rhs_ty :: Kind
rhs_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
in_env (CoreExpr -> Kind
exprType CoreExpr
rhs)
rhs_rep :: Kind
rhs_rep = HasDebugCallStack => Kind -> Kind
Kind -> Kind
getRuntimeRep Kind
rhs_ty
out_args :: [ArgSpec]
out_args = [ TyArg :: Kind -> Kind -> ArgSpec
TyArg { as_arg_ty :: Kind
as_arg_ty = Kind
rhs_rep
, as_hole_ty :: Kind
as_hole_ty = Kind
seq_id_ty }
, TyArg :: Kind -> Kind -> ArgSpec
TyArg { as_arg_ty :: Kind
as_arg_ty = Kind
scrut_ty
, as_hole_ty :: Kind
as_hole_ty = Kind
res1_ty }
, TyArg :: Kind -> Kind -> ArgSpec
TyArg { as_arg_ty :: Kind
as_arg_ty = Kind
rhs_ty
, as_hole_ty :: Kind
as_hole_ty = Kind
res2_ty }
, ValArg :: Demand -> CoreExpr -> Kind -> ArgSpec
ValArg { as_arg :: CoreExpr
as_arg = CoreExpr
no_cast_scrut
, as_dmd :: Demand
as_dmd = Demand
seqDmd
, as_hole_ty :: Kind
as_hole_ty = Kind
res3_ty } ]
rule_cont :: SimplCont
rule_cont = ApplyToVal :: DupFlag -> Kind -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
ApplyToVal { sc_dup :: DupFlag
sc_dup = DupFlag
NoDup, sc_arg :: CoreExpr
sc_arg = CoreExpr
rhs
, sc_env :: SimplEnv
sc_env = SimplEnv
in_env, sc_cont :: SimplCont
sc_cont = SimplCont
cont
, sc_hole_ty :: Kind
sc_hole_ty = Kind
res4_ty }
drop_casts :: Expr b -> Expr b
drop_casts (Cast Expr b
e Coercion
_) = Expr b -> Expr b
drop_casts Expr b
e
drop_casts Expr b
e = Expr b
e
rebuildCase, reallyRebuildCase
:: SimplEnv
-> OutExpr
-> InId
-> [InAlt]
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
rebuildCase :: SimplEnv
-> CoreExpr
-> Id
-> [Alt Id]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
rebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont
| Lit Literal
lit <- CoreExpr
scrut
, Bool -> Bool
not (Literal -> Bool
litIsLifted Literal
lit)
= do { Tick -> SimplM ()
tick (Id -> Tick
KnownBranch Id
case_bndr)
; case AltCon -> [Alt Id] -> Maybe (Alt Id)
forall a b. AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt (Literal -> AltCon
LitAlt Literal
lit) [Alt Id]
alts of
Maybe (Alt Id)
Nothing -> SimplEnv
-> Id -> [Alt Id] -> SimplCont -> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env Id
case_bndr [Alt Id]
alts SimplCont
cont
Just (AltCon
_, [Id]
bs, CoreExpr
rhs) -> SimplEnv
-> [FloatBind]
-> CoreExpr
-> [Id]
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
forall {t :: * -> *} {a}.
Foldable t =>
SimplEnv
-> [FloatBind]
-> CoreExpr
-> t a
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env [] CoreExpr
scrut [Id]
bs CoreExpr
rhs }
| Just (InScopeSet
in_scope', [FloatBind]
wfloats, DataCon
con, [Kind]
ty_args, [CoreExpr]
other_args)
<- InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Kind], [CoreExpr])
HasDebugCallStack =>
InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Kind], [CoreExpr])
exprIsConApp_maybe (SimplEnv -> InScopeEnv
getUnfoldingInRuleMatch SimplEnv
env) CoreExpr
scrut
, let env0 :: SimplEnv
env0 = SimplEnv -> InScopeSet -> SimplEnv
setInScopeSet SimplEnv
env InScopeSet
in_scope'
= do { Tick -> SimplM ()
tick (Id -> Tick
KnownBranch Id
case_bndr)
; let scaled_wfloats :: [FloatBind]
scaled_wfloats = (FloatBind -> FloatBind) -> [FloatBind] -> [FloatBind]
forall a b. (a -> b) -> [a] -> [b]
map FloatBind -> FloatBind
scale_float [FloatBind]
wfloats
; case AltCon -> [Alt Id] -> Maybe (Alt Id)
forall a b. AltCon -> [(AltCon, a, b)] -> Maybe (AltCon, a, b)
findAlt (DataCon -> AltCon
DataAlt DataCon
con) [Alt Id]
alts of
Maybe (Alt Id)
Nothing -> SimplEnv
-> Id -> [Alt Id] -> SimplCont -> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env0 Id
case_bndr [Alt Id]
alts SimplCont
cont
Just (AltCon
DEFAULT, [Id]
bs, CoreExpr
rhs) -> let con_app :: CoreExpr
con_app = Id -> CoreExpr
forall b. Id -> Expr b
Var (DataCon -> Id
dataConWorkId DataCon
con)
CoreExpr -> [Kind] -> CoreExpr
forall b. Expr b -> [Kind] -> Expr b
`mkTyApps` [Kind]
ty_args
CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
`mkApps` [CoreExpr]
other_args
in SimplEnv
-> [FloatBind]
-> CoreExpr
-> [Id]
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
forall {t :: * -> *} {a}.
Foldable t =>
SimplEnv
-> [FloatBind]
-> CoreExpr
-> t a
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env0 [FloatBind]
scaled_wfloats CoreExpr
con_app [Id]
bs CoreExpr
rhs
Just (AltCon
_, [Id]
bs, CoreExpr
rhs) -> SimplEnv
-> CoreExpr
-> [FloatBind]
-> DataCon
-> [Kind]
-> [CoreExpr]
-> Id
-> [Id]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
knownCon SimplEnv
env0 CoreExpr
scrut [FloatBind]
scaled_wfloats DataCon
con [Kind]
ty_args [CoreExpr]
other_args
Id
case_bndr [Id]
bs CoreExpr
rhs SimplCont
cont
}
where
simple_rhs :: SimplEnv
-> [FloatBind]
-> CoreExpr
-> t a
-> CoreExpr
-> SimplM (SimplFloats, CoreExpr)
simple_rhs SimplEnv
env [FloatBind]
wfloats CoreExpr
scrut' t a
bs CoreExpr
rhs =
ASSERT( null bs )
do { (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env Id
case_bndr CoreExpr
scrut'
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont
; case [FloatBind]
wfloats of
[] -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr')
[FloatBind]
_ -> (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return
( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env,
[FloatBind] -> CoreExpr -> CoreExpr
GHC.Core.Make.wrapFloats [FloatBind]
wfloats (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
SimplFloats -> CoreExpr -> CoreExpr
wrapFloats (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2) CoreExpr
expr' )}
scale_float :: FloatBind -> FloatBind
scale_float (GHC.Core.Make.FloatCase CoreExpr
scrut Id
case_bndr AltCon
con [Id]
vars) =
let
scale_id :: Id -> Id
scale_id Id
id = Kind -> Id -> Id
scaleVarBy Kind
holeScaling Id
id
in
CoreExpr -> Id -> AltCon -> [Id] -> FloatBind
GHC.Core.Make.FloatCase CoreExpr
scrut (Id -> Id
scale_id Id
case_bndr) AltCon
con ((Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Id
scale_id [Id]
vars)
scale_float FloatBind
f = FloatBind
f
holeScaling :: Kind
holeScaling = SimplCont -> Kind
contHoleScaling SimplCont
cont Kind -> Kind -> Kind
`mkMultMul` Id -> Kind
idMult Id
case_bndr
rebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr alts :: [Alt Id]
alts@[(AltCon
_, [Id]
bndrs, CoreExpr
rhs)] SimplCont
cont
| Bool
is_plain_seq
, CoreExpr -> Bool
exprOkForSideEffects CoreExpr
scrut
= SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env CoreExpr
rhs SimplCont
cont
| Bool
all_dead_bndrs
, CoreExpr -> Id -> Bool
doCaseToLet CoreExpr
scrut Id
case_bndr
= do { Tick -> SimplM ()
tick (Id -> Tick
CaseElim Id
case_bndr)
; (SimplFloats
floats1, SimplEnv
env') <- SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env Id
case_bndr CoreExpr
scrut
; (SimplFloats
floats2, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rhs SimplCont
cont
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, CoreExpr
expr') }
| Bool
is_plain_seq
= do { Maybe (SimplEnv, CoreExpr, SimplCont)
mb_rule <- SimplEnv
-> CoreExpr
-> CoreExpr
-> SimplCont
-> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont))
trySeqRules SimplEnv
env CoreExpr
scrut CoreExpr
rhs SimplCont
cont
; case Maybe (SimplEnv, CoreExpr, SimplCont)
mb_rule of
Just (SimplEnv
env', CoreExpr
rule_rhs, SimplCont
cont') -> SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env' CoreExpr
rule_rhs SimplCont
cont'
Maybe (SimplEnv, CoreExpr, SimplCont)
Nothing -> SimplEnv
-> CoreExpr
-> Id
-> [Alt Id]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont }
where
all_dead_bndrs :: Bool
all_dead_bndrs = (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isDeadBinder [Id]
bndrs
is_plain_seq :: Bool
is_plain_seq = Bool
all_dead_bndrs Bool -> Bool -> Bool
&& Id -> Bool
isDeadBinder Id
case_bndr
rebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont
= SimplEnv
-> CoreExpr
-> Id
-> [Alt Id]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont
doCaseToLet :: OutExpr
-> InId
-> Bool
doCaseToLet :: CoreExpr -> Id -> Bool
doCaseToLet CoreExpr
scrut Id
case_bndr
| Id -> Bool
isTyCoVar Id
case_bndr
= CoreExpr -> Bool
forall {b}. Expr b -> Bool
isTyCoArg CoreExpr
scrut
| HasDebugCallStack => Kind -> Bool
Kind -> Bool
isUnliftedType (Id -> Kind
idType Id
case_bndr)
= CoreExpr -> Bool
exprOkForSpeculation CoreExpr
scrut
| Bool
otherwise
= CoreExpr -> Bool
exprIsHNF CoreExpr
scrut
Bool -> Bool -> Bool
|| Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isStrictDmd (Id -> Demand
idDemandInfo Id
case_bndr)
reallyRebuildCase :: SimplEnv
-> CoreExpr
-> Id
-> [Alt Id]
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
reallyRebuildCase SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont
| Bool -> Bool
not (SimplMode -> Bool
sm_case_case (SimplEnv -> SimplMode
getMode SimplEnv
env))
= do { CoreExpr
case_expr <- SimplEnv
-> CoreExpr -> Id -> [Alt Id] -> SimplCont -> SimplM CoreExpr
simplAlts SimplEnv
env CoreExpr
scrut Id
case_bndr [Alt Id]
alts
(Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contHoleType SimplCont
cont))
; SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuild SimplEnv
env CoreExpr
case_expr SimplCont
cont }
| Bool
otherwise
= do { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Alt Id] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCaseCont SimplEnv
env [Alt Id]
alts SimplCont
cont
; CoreExpr
case_expr <- SimplEnv
-> CoreExpr -> Id -> [Alt Id] -> SimplCont -> SimplM CoreExpr
simplAlts (SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats)
CoreExpr
scrut (Kind -> Id -> Id
scaleIdBy Kind
holeScaling Id
case_bndr) (Kind -> [Alt Id] -> [Alt Id]
scaleAltsBy Kind
holeScaling [Alt Id]
alts) SimplCont
cont'
; (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, CoreExpr
case_expr) }
where
holeScaling :: Kind
holeScaling = SimplCont -> Kind
contHoleScaling SimplCont
cont
simplAlts :: SimplEnv
-> OutExpr
-> InId
-> [InAlt]
-> SimplCont
-> SimplM OutExpr
simplAlts :: SimplEnv
-> CoreExpr -> Id -> [Alt Id] -> SimplCont -> SimplM CoreExpr
simplAlts SimplEnv
env0 CoreExpr
scrut Id
case_bndr [Alt Id]
alts SimplCont
cont'
= do { [Char] -> SDoc -> SimplM ()
traceSmpl [Char]
"simplAlts" ([SDoc] -> SDoc
vcat [ Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
case_bndr
, [Char] -> SDoc
text [Char]
"cont':" SDoc -> SDoc -> SDoc
<+> SimplCont -> SDoc
forall a. Outputable a => a -> SDoc
ppr SimplCont
cont'
, [Char] -> SDoc
text [Char]
"in_scope" SDoc -> SDoc -> SDoc
<+> InScopeSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr (SimplEnv -> InScopeSet
seInScope SimplEnv
env0) ])
; (SimplEnv
env1, Id
case_bndr1) <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
env0 Id
case_bndr
; let case_bndr2 :: Id
case_bndr2 = Id
case_bndr1 Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
evaldUnfolding
env2 :: SimplEnv
env2 = SimplEnv -> Id -> SimplEnv
modifyInScope SimplEnv
env1 Id
case_bndr2
; (FamInstEnv, FamInstEnv)
fam_envs <- SimplM (FamInstEnv, FamInstEnv)
getFamEnvs
; (SimplEnv
alt_env', CoreExpr
scrut', Id
case_bndr') <- (FamInstEnv, FamInstEnv)
-> SimplEnv
-> CoreExpr
-> Id
-> Id
-> [Alt Id]
-> SimplM (SimplEnv, CoreExpr, Id)
improveSeq (FamInstEnv, FamInstEnv)
fam_envs SimplEnv
env2 CoreExpr
scrut
Id
case_bndr Id
case_bndr2 [Alt Id]
alts
; ([AltCon]
imposs_deflt_cons, [Alt Id]
in_alts) <- CoreExpr -> Id -> [Alt Id] -> SimplM ([AltCon], [Alt Id])
prepareAlts CoreExpr
scrut' Id
case_bndr' [Alt Id]
alts
; [Alt Id]
alts' <- (Alt Id -> SimplM (Alt Id)) -> [Alt Id] -> SimplM [Alt Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> Id
-> SimplCont
-> Alt Id
-> SimplM (Alt Id)
simplAlt SimplEnv
alt_env' (CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just CoreExpr
scrut') [AltCon]
imposs_deflt_cons Id
case_bndr' SimplCont
cont') [Alt Id]
in_alts
;
; let alts_ty' :: Kind
alts_ty' = SimplCont -> Kind
contResultType SimplCont
cont'
; Kind -> ()
seqType Kind
alts_ty' () -> SimplM CoreExpr -> SimplM CoreExpr
`seq`
DynFlags -> CoreExpr -> Id -> Kind -> [Alt Id] -> SimplM CoreExpr
mkCase (SimplEnv -> DynFlags
seDynFlags SimplEnv
env0) CoreExpr
scrut' Id
case_bndr' Kind
alts_ty' [Alt Id]
alts' }
improveSeq :: (FamInstEnv, FamInstEnv) -> SimplEnv
-> OutExpr -> InId -> OutId -> [InAlt]
-> SimplM (SimplEnv, OutExpr, OutId)
improveSeq :: (FamInstEnv, FamInstEnv)
-> SimplEnv
-> CoreExpr
-> Id
-> Id
-> [Alt Id]
-> SimplM (SimplEnv, CoreExpr, Id)
improveSeq (FamInstEnv, FamInstEnv)
fam_envs SimplEnv
env CoreExpr
scrut Id
case_bndr Id
case_bndr1 [(AltCon
DEFAULT,[Id]
_,CoreExpr
_)]
| Just (Coercion
co, Kind
ty2) <- (FamInstEnv, FamInstEnv) -> Kind -> Maybe (Coercion, Kind)
topNormaliseType_maybe (FamInstEnv, FamInstEnv)
fam_envs (Id -> Kind
idType Id
case_bndr1)
= do { Id
case_bndr2 <- FastString -> Kind -> Kind -> SimplM Id
newId ([Char] -> FastString
fsLit [Char]
"nt") Kind
Many Kind
ty2
; let rhs :: SimplSR
rhs = CoreExpr -> Maybe JoinArity -> SimplSR
DoneEx (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
case_bndr2 CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
`Cast` Coercion -> Coercion
mkSymCo Coercion
co) Maybe JoinArity
forall a. Maybe a
Nothing
env2 :: SimplEnv
env2 = SimplEnv -> Id -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env Id
case_bndr SimplSR
rhs
; (SimplEnv, CoreExpr, Id) -> SimplM (SimplEnv, CoreExpr, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env2, CoreExpr
scrut CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
`Cast` Coercion
co, Id
case_bndr2) }
improveSeq (FamInstEnv, FamInstEnv)
_ SimplEnv
env CoreExpr
scrut Id
_ Id
case_bndr1 [Alt Id]
_
= (SimplEnv, CoreExpr, Id) -> SimplM (SimplEnv, CoreExpr, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env, CoreExpr
scrut, Id
case_bndr1)
simplAlt :: SimplEnv
-> Maybe OutExpr
-> [AltCon]
-> OutId
-> SimplCont
-> InAlt
-> SimplM OutAlt
simplAlt :: SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> Id
-> SimplCont
-> Alt Id
-> SimplM (Alt Id)
simplAlt SimplEnv
env Maybe CoreExpr
_ [AltCon]
imposs_deflt_cons Id
case_bndr' SimplCont
cont' (AltCon
DEFAULT, [Id]
bndrs, CoreExpr
rhs)
= ASSERT( null bndrs )
do { let env' :: SimplEnv
env' = SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env Id
case_bndr'
([AltCon] -> Unfolding
mkOtherCon [AltCon]
imposs_deflt_cons)
; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
rhs SimplCont
cont'
; Alt Id -> SimplM (Alt Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (AltCon
DEFAULT, [], CoreExpr
rhs') }
simplAlt SimplEnv
env Maybe CoreExpr
scrut' [AltCon]
_ Id
case_bndr' SimplCont
cont' (LitAlt Literal
lit, [Id]
bndrs, CoreExpr
rhs)
= ASSERT( null bndrs )
do { SimplEnv
env' <- SimplEnv -> Maybe CoreExpr -> Id -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env Maybe CoreExpr
scrut' Id
case_bndr' (Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
lit)
; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env' CoreExpr
rhs SimplCont
cont'
; Alt Id -> SimplM (Alt Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> AltCon
LitAlt Literal
lit, [], CoreExpr
rhs') }
simplAlt SimplEnv
env Maybe CoreExpr
scrut' [AltCon]
_ Id
case_bndr' SimplCont
cont' (DataAlt DataCon
con, [Id]
vs, CoreExpr
rhs)
= do {
let vs_with_evals :: [Id]
vs_with_evals = Maybe CoreExpr -> DataCon -> [Id] -> [Id]
addEvals Maybe CoreExpr
scrut' DataCon
con [Id]
vs
; (SimplEnv
env', [Id]
vs') <- SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplLamBndrs SimplEnv
env [Id]
vs_with_evals
; let inst_tys' :: [Kind]
inst_tys' = Kind -> [Kind]
tyConAppArgs (Id -> Kind
idType Id
case_bndr')
con_app :: OutExpr
con_app :: CoreExpr
con_app = DataCon -> [Kind] -> [Id] -> CoreExpr
forall b. DataCon -> [Kind] -> [Id] -> Expr b
mkConApp2 DataCon
con [Kind]
inst_tys' [Id]
vs'
; SimplEnv
env'' <- SimplEnv -> Maybe CoreExpr -> Id -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env' Maybe CoreExpr
scrut' Id
case_bndr' CoreExpr
con_app
; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
env'' CoreExpr
rhs SimplCont
cont'
; Alt Id -> SimplM (Alt Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (DataCon -> AltCon
DataAlt DataCon
con, [Id]
vs', CoreExpr
rhs') }
addEvals :: Maybe OutExpr -> DataCon -> [Id] -> [Id]
addEvals :: Maybe CoreExpr -> DataCon -> [Id] -> [Id]
addEvals Maybe CoreExpr
scrut DataCon
con [Id]
vs
| Just CoreExpr
scr <- Maybe CoreExpr
scrut
, DataCon -> Bool
isUnboxedTupleCon DataCon
con
, [Id
s,Id
x] <- [Id]
vs
, Just (Var Id
f) <- Word -> CoreExpr -> Maybe CoreExpr
forall a. Word -> Expr a -> Maybe (Expr a)
stripNArgs Word
4 CoreExpr
scr
, Just PrimOp
SeqOp <- Id -> Maybe PrimOp
isPrimOpId_maybe Id
f
, let x' :: Id
x' = StrictnessMark -> Id -> Id
zapIdOccInfoAndSetEvald StrictnessMark
MarkedStrict Id
x
= [Id
s, Id
x']
addEvals Maybe CoreExpr
_scrut DataCon
con [Id]
vs = [Id] -> [StrictnessMark] -> [Id]
go [Id]
vs [StrictnessMark]
the_strs
where
the_strs :: [StrictnessMark]
the_strs = DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con
go :: [Id] -> [StrictnessMark] -> [Id]
go [] [] = []
go (Id
v:[Id]
vs') [StrictnessMark]
strs | Id -> Bool
isTyVar Id
v = Id
v Id -> [Id] -> [Id]
forall a. a -> [a] -> [a]
: [Id] -> [StrictnessMark] -> [Id]
go [Id]
vs' [StrictnessMark]
strs
go (Id
v:[Id]
vs') (StrictnessMark
str:[StrictnessMark]
strs) = StrictnessMark -> Id -> Id
zapIdOccInfoAndSetEvald StrictnessMark
str Id
v Id -> [Id] -> [Id]
forall a. a -> [a] -> [a]
: [Id] -> [StrictnessMark] -> [Id]
go [Id]
vs' [StrictnessMark]
strs
go [Id]
_ [StrictnessMark]
_ = [Char] -> SDoc -> [Id]
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"Simplify.addEvals"
(DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
con SDoc -> SDoc -> SDoc
$$
[Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
vs SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length ((StrictnessMark -> SDoc) -> [StrictnessMark] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map StrictnessMark -> SDoc
strdisp [StrictnessMark]
the_strs) SDoc -> SDoc -> SDoc
$$
[Scaled Kind] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length (DataCon -> [Scaled Kind]
dataConRepArgTys DataCon
con) SDoc -> SDoc -> SDoc
$$
[StrictnessMark] -> SDoc
forall {t :: * -> *} {a}.
(Outputable (t a), Foldable t) =>
t a -> SDoc
ppr_with_length (DataCon -> [StrictnessMark]
dataConRepStrictness DataCon
con))
where
ppr_with_length :: t a -> SDoc
ppr_with_length t a
list
= t a -> SDoc
forall a. Outputable a => a -> SDoc
ppr t a
list SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
parens ([Char] -> SDoc
text [Char]
"length =" SDoc -> SDoc -> SDoc
<+> JoinArity -> SDoc
forall a. Outputable a => a -> SDoc
ppr (t a -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length t a
list))
strdisp :: StrictnessMark -> SDoc
strdisp StrictnessMark
MarkedStrict = [Char] -> SDoc
text [Char]
"MarkedStrict"
strdisp StrictnessMark
NotMarkedStrict = [Char] -> SDoc
text [Char]
"NotMarkedStrict"
zapIdOccInfoAndSetEvald :: StrictnessMark -> Id -> Id
zapIdOccInfoAndSetEvald :: StrictnessMark -> Id -> Id
zapIdOccInfoAndSetEvald StrictnessMark
str Id
v =
StrictnessMark -> Id -> Id
setCaseBndrEvald StrictnessMark
str (Id -> Id) -> Id -> Id
forall a b. (a -> b) -> a -> b
$
Id -> Id
zapIdOccInfo Id
v
addAltUnfoldings :: SimplEnv -> Maybe OutExpr -> OutId -> OutExpr -> SimplM SimplEnv
addAltUnfoldings :: SimplEnv -> Maybe CoreExpr -> Id -> CoreExpr -> SimplM SimplEnv
addAltUnfoldings SimplEnv
env Maybe CoreExpr
scrut Id
case_bndr CoreExpr
con_app
= do { let con_app_unf :: Unfolding
con_app_unf = CoreExpr -> Unfolding
mk_simple_unf CoreExpr
con_app
env1 :: SimplEnv
env1 = SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env Id
case_bndr Unfolding
con_app_unf
env2 :: SimplEnv
env2 | Kind
Many <- Id -> Kind
idMult Id
case_bndr = case Maybe CoreExpr
scrut of
Just (Var Id
v) -> SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env1 Id
v Unfolding
con_app_unf
Just (Cast (Var Id
v) Coercion
co) -> SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env1 Id
v (Unfolding -> SimplEnv) -> Unfolding -> SimplEnv
forall a b. (a -> b) -> a -> b
$
CoreExpr -> Unfolding
mk_simple_unf (CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
con_app (Coercion -> Coercion
mkSymCo Coercion
co))
Maybe CoreExpr
_ -> SimplEnv
env1
| Bool
otherwise = SimplEnv
env1
; [Char] -> SDoc -> SimplM ()
traceSmpl [Char]
"addAltUnf" ([SDoc] -> SDoc
vcat [Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
case_bndr SDoc -> SDoc -> SDoc
<+> Maybe CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe CoreExpr
scrut, CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
con_app])
; SimplEnv -> SimplM SimplEnv
forall (m :: * -> *) a. Monad m => a -> m a
return SimplEnv
env2 }
where
mk_simple_unf :: CoreExpr -> Unfolding
mk_simple_unf = DynFlags -> CoreExpr -> Unfolding
mkSimpleUnfolding (SimplEnv -> DynFlags
seDynFlags SimplEnv
env)
addBinderUnfolding :: SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding :: SimplEnv -> Id -> Unfolding -> SimplEnv
addBinderUnfolding SimplEnv
env Id
bndr Unfolding
unf
| Bool
debugIsOn, Just CoreExpr
tmpl <- Unfolding -> Maybe CoreExpr
maybeUnfoldingTemplate Unfolding
unf
= WARN( not (eqType (idType bndr) (exprType tmpl)),
ppr bndr $$ ppr (idType bndr) $$ ppr tmpl $$ ppr (exprType tmpl) )
SimplEnv -> Id -> SimplEnv
modifyInScope SimplEnv
env (Id
bndr Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
unf)
| Bool
otherwise
= SimplEnv -> Id -> SimplEnv
modifyInScope SimplEnv
env (Id
bndr Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
unf)
zapBndrOccInfo :: Bool -> Id -> Id
zapBndrOccInfo :: Bool -> Id -> Id
zapBndrOccInfo Bool
keep_occ_info Id
pat_id
| Bool
keep_occ_info = Id
pat_id
| Bool
otherwise = Id -> Id
zapIdOccInfo Id
pat_id
knownCon :: SimplEnv
-> OutExpr
-> [FloatBind] -> DataCon -> [OutType] -> [OutExpr]
-> InId -> [InBndr] -> InExpr
-> SimplCont
-> SimplM (SimplFloats, OutExpr)
knownCon :: SimplEnv
-> CoreExpr
-> [FloatBind]
-> DataCon
-> [Kind]
-> [CoreExpr]
-> Id
-> [Id]
-> CoreExpr
-> SimplCont
-> SimplM (SimplFloats, CoreExpr)
knownCon SimplEnv
env CoreExpr
scrut [FloatBind]
dc_floats DataCon
dc [Kind]
dc_ty_args [CoreExpr]
dc_args Id
bndr [Id]
bs CoreExpr
rhs SimplCont
cont
= do { (SimplFloats
floats1, SimplEnv
env1) <- SimplEnv -> [Id] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env [Id]
bs [CoreExpr]
dc_args
; (SimplFloats
floats2, SimplEnv
env2) <- SimplEnv -> SimplM (SimplFloats, SimplEnv)
bind_case_bndr SimplEnv
env1
; (SimplFloats
floats3, CoreExpr
expr') <- SimplEnv -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplExprF SimplEnv
env2 CoreExpr
rhs SimplCont
cont
; case [FloatBind]
dc_floats of
[] ->
(SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3, CoreExpr
expr')
[FloatBind]
_ ->
(SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
, [FloatBind] -> CoreExpr -> CoreExpr
GHC.Core.Make.wrapFloats [FloatBind]
dc_floats (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
SimplFloats -> CoreExpr -> CoreExpr
wrapFloats (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats3) CoreExpr
expr') }
where
zap_occ :: Id -> Id
zap_occ = Bool -> Id -> Id
zapBndrOccInfo (Id -> Bool
isDeadBinder Id
bndr)
bind_args :: SimplEnv -> [Id] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env' [] [CoreExpr]
_ = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env', SimplEnv
env')
bind_args SimplEnv
env' (Id
b:[Id]
bs') (Type Kind
ty : [CoreExpr]
args)
= ASSERT( isTyVar b )
SimplEnv -> [Id] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args (SimplEnv -> Id -> Kind -> SimplEnv
extendTvSubst SimplEnv
env' Id
b Kind
ty) [Id]
bs' [CoreExpr]
args
bind_args SimplEnv
env' (Id
b:[Id]
bs') (Coercion Coercion
co : [CoreExpr]
args)
= ASSERT( isCoVar b )
SimplEnv -> [Id] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args (SimplEnv -> Id -> Coercion -> SimplEnv
extendCvSubst SimplEnv
env' Id
b Coercion
co) [Id]
bs' [CoreExpr]
args
bind_args SimplEnv
env' (Id
b:[Id]
bs') (CoreExpr
arg : [CoreExpr]
args)
= ASSERT( isId b )
do { let b' :: Id
b' = Id -> Id
zap_occ Id
b
; (SimplFloats
floats1, SimplEnv
env2) <- SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env' Id
b' CoreExpr
arg
; (SimplFloats
floats2, SimplEnv
env3) <- SimplEnv -> [Id] -> [CoreExpr] -> SimplM (SimplFloats, SimplEnv)
bind_args SimplEnv
env2 [Id]
bs' [CoreExpr]
args
; (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats1 SimplFloats -> SimplFloats -> SimplFloats
`addFloats` SimplFloats
floats2, SimplEnv
env3) }
bind_args SimplEnv
_ [Id]
_ [CoreExpr]
_ =
[Char] -> SDoc -> SimplM (SimplFloats, SimplEnv)
forall a. HasCallStack => [Char] -> SDoc -> a
pprPanic [Char]
"bind_args" (SDoc -> SimplM (SimplFloats, SimplEnv))
-> SDoc -> SimplM (SimplFloats, SimplEnv)
forall a b. (a -> b) -> a -> b
$ DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc SDoc -> SDoc -> SDoc
$$ [Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
bs SDoc -> SDoc -> SDoc
$$ [CoreExpr] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreExpr]
dc_args SDoc -> SDoc -> SDoc
$$
[Char] -> SDoc
text [Char]
"scrut:" SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
scrut
bind_case_bndr :: SimplEnv -> SimplM (SimplFloats, SimplEnv)
bind_case_bndr SimplEnv
env
| Id -> Bool
isDeadBinder Id
bndr = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplEnv
env)
| CoreExpr -> Bool
exprIsTrivial CoreExpr
scrut = (SimplFloats, SimplEnv) -> SimplM (SimplFloats, SimplEnv)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
, SimplEnv -> Id -> SimplSR -> SimplEnv
extendIdSubst SimplEnv
env Id
bndr (CoreExpr -> Maybe JoinArity -> SimplSR
DoneEx CoreExpr
scrut Maybe JoinArity
forall a. Maybe a
Nothing))
| Bool
otherwise = do { [CoreExpr]
dc_args <- (Id -> SimplM CoreExpr) -> [Id] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> Id -> SimplM CoreExpr
simplVar SimplEnv
env) [Id]
bs
; let con_app :: CoreExpr
con_app = Id -> CoreExpr
forall b. Id -> Expr b
Var (DataCon -> Id
dataConWorkId DataCon
dc)
CoreExpr -> [Kind] -> CoreExpr
forall b. Expr b -> [Kind] -> Expr b
`mkTyApps` [Kind]
dc_ty_args
CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
`mkApps` [CoreExpr]
dc_args
; SimplEnv -> Id -> CoreExpr -> SimplM (SimplFloats, SimplEnv)
simplNonRecX SimplEnv
env Id
bndr CoreExpr
con_app }
missingAlt :: SimplEnv -> Id -> [InAlt] -> SimplCont
-> SimplM (SimplFloats, OutExpr)
missingAlt :: SimplEnv
-> Id -> [Alt Id] -> SimplCont -> SimplM (SimplFloats, CoreExpr)
missingAlt SimplEnv
env Id
case_bndr [Alt Id]
_ SimplCont
cont
= WARN( True, text "missingAlt" <+> ppr case_bndr )
let cont_ty :: Kind
cont_ty = SimplCont -> Kind
contResultType SimplCont
cont
in Kind -> ()
seqType Kind
cont_ty ()
-> SimplM (SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
`seq`
(SimplFloats, CoreExpr) -> SimplM (SimplFloats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, Kind -> CoreExpr
mkImpossibleExpr Kind
cont_ty)
mkDupableCaseCont :: SimplEnv -> [InAlt] -> SimplCont
-> SimplM (SimplFloats, SimplCont)
mkDupableCaseCont :: SimplEnv
-> [Alt Id] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCaseCont SimplEnv
env [Alt Id]
alts SimplCont
cont
| [Alt Id] -> Bool
altsWouldDup [Alt Id]
alts = SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
| Bool
otherwise = (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplCont
cont)
altsWouldDup :: [InAlt] -> Bool
altsWouldDup :: [Alt Id] -> Bool
altsWouldDup [] = Bool
False
altsWouldDup [Alt Id
_] = Bool
False
altsWouldDup (Alt Id
alt:[Alt Id]
alts)
| Alt Id -> Bool
forall {a} {b}. (a, b, CoreExpr) -> Bool
is_bot_alt Alt Id
alt = [Alt Id] -> Bool
altsWouldDup [Alt Id]
alts
| Bool
otherwise = Bool -> Bool
not ((Alt Id -> Bool) -> [Alt Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Alt Id -> Bool
forall {a} {b}. (a, b, CoreExpr) -> Bool
is_bot_alt [Alt Id]
alts)
where
is_bot_alt :: (a, b, CoreExpr) -> Bool
is_bot_alt (a
_,b
_,CoreExpr
rhs) = CoreExpr -> Bool
exprIsDeadEnd CoreExpr
rhs
mkDupableCont :: SimplEnv
-> SimplCont
-> SimplM ( SimplFloats
, SimplCont)
mkDupableCont :: SimplEnv -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCont SimplEnv
env SimplCont
cont
= SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env (Demand -> [Demand]
forall a. a -> [a]
repeat Demand
topDmd) SimplCont
cont
mkDupableContWithDmds
:: SimplEnv -> [Demand]
-> SimplCont -> SimplM ( SimplFloats, SimplCont)
mkDupableContWithDmds :: SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
_ SimplCont
cont
| SimplCont -> Bool
contIsDupable SimplCont
cont
= (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env, SimplCont
cont)
mkDupableContWithDmds SimplEnv
_ [Demand]
_ (Stop {}) = [Char] -> SimplM (SimplFloats, SimplCont)
forall a. [Char] -> a
panic [Char]
"mkDupableCont"
mkDupableContWithDmds SimplEnv
env [Demand]
dmds (CastIt Coercion
ty SimplCont
cont)
= do { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, Coercion -> SimplCont -> SimplCont
CastIt Coercion
ty SimplCont
cont') }
mkDupableContWithDmds SimplEnv
env [Demand]
dmds (TickIt Tickish Id
t SimplCont
cont)
= do { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, Tickish Id -> SimplCont -> SimplCont
TickIt Tickish Id
t SimplCont
cont') }
mkDupableContWithDmds SimplEnv
env [Demand]
_
(StrictBind { sc_bndr :: SimplCont -> Id
sc_bndr = Id
bndr, sc_bndrs :: SimplCont -> [Id]
sc_bndrs = [Id]
bndrs
, sc_body :: SimplCont -> CoreExpr
sc_body = CoreExpr
body, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont})
= do { let sb_env :: SimplEnv
sb_env = SimplEnv
se SimplEnv -> SimplEnv -> SimplEnv
`setInScopeFromE` SimplEnv
env
; (SimplEnv
sb_env1, Id
bndr') <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
sb_env Id
bndr
; (SimplFloats
floats1, CoreExpr
join_inner) <- SimplEnv
-> [Id] -> CoreExpr -> SimplCont -> SimplM (SimplFloats, CoreExpr)
simplLam SimplEnv
sb_env1 [Id]
bndrs CoreExpr
body SimplCont
cont
; let join_body :: CoreExpr
join_body = SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats1 CoreExpr
join_inner
res_ty :: Kind
res_ty = SimplCont -> Kind
contResultType SimplCont
cont
; SimplEnv
-> Id -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env Id
bndr' CoreExpr
join_body Kind
res_ty }
mkDupableContWithDmds SimplEnv
env [Demand]
_
(StrictArg { sc_fun :: SimplCont -> ArgInfo
sc_fun = ArgInfo
fun, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont
, sc_fun_ty :: SimplCont -> Kind
sc_fun_ty = Kind
fun_ty })
| Maybe DataCon -> Bool
forall a. Maybe a -> Bool
isNothing (Id -> Maybe DataCon
isDataConId_maybe (ArgInfo -> Id
ai_fun ArgInfo
fun))
, SimplCont -> Bool
thumbsUpPlanA SimplCont
cont
=
do { let (Demand
_ : [Demand]
dmds) = ArgInfo -> [Demand]
ai_dmds ArgInfo
fun
; (SimplFloats
floats1, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
; ([LetFloats]
floats_s, [ArgSpec]
args') <- (ArgSpec -> SimplM (LetFloats, ArgSpec))
-> [ArgSpec] -> SimplM ([LetFloats], [ArgSpec])
forall (m :: * -> *) a b c.
Applicative m =>
(a -> m (b, c)) -> [a] -> m ([b], [c])
mapAndUnzipM (SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
makeTrivialArg (SimplEnv -> SimplMode
getMode SimplEnv
env))
(ArgInfo -> [ArgSpec]
ai_args ArgInfo
fun)
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( (SimplFloats -> LetFloats -> SimplFloats)
-> SimplFloats -> [LetFloats] -> SimplFloats
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SimplFloats -> LetFloats -> SimplFloats
addLetFloats SimplFloats
floats1 [LetFloats]
floats_s
, StrictArg :: DupFlag -> ArgInfo -> Kind -> SimplCont -> SimplCont
StrictArg { sc_fun :: ArgInfo
sc_fun = ArgInfo
fun { ai_args :: [ArgSpec]
ai_args = [ArgSpec]
args' }
, sc_cont :: SimplCont
sc_cont = SimplCont
cont'
, sc_fun_ty :: Kind
sc_fun_ty = Kind
fun_ty
, sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup} ) }
| Bool
otherwise
=
do { let rhs_ty :: Kind
rhs_ty = SimplCont -> Kind
contResultType SimplCont
cont
(Kind
m,Kind
arg_ty,Kind
_) = Kind -> (Kind, Kind, Kind)
splitFunTy Kind
fun_ty
; Id
arg_bndr <- FastString -> Kind -> Kind -> SimplM Id
newId ([Char] -> FastString
fsLit [Char]
"arg") Kind
m Kind
arg_ty
; let env' :: SimplEnv
env' = SimplEnv
env SimplEnv -> [Id] -> SimplEnv
`addNewInScopeIds` [Id
arg_bndr]
; (SimplFloats
floats, CoreExpr
join_rhs) <- SimplEnv -> ArgInfo -> SimplCont -> SimplM (SimplFloats, CoreExpr)
rebuildCall SimplEnv
env' (ArgInfo -> CoreExpr -> Kind -> ArgInfo
addValArgTo ArgInfo
fun (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
arg_bndr) Kind
fun_ty) SimplCont
cont
; SimplEnv
-> Id -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env' Id
arg_bndr (SimplFloats -> CoreExpr -> CoreExpr
wrapFloats SimplFloats
floats CoreExpr
join_rhs) Kind
rhs_ty }
where
thumbsUpPlanA :: SimplCont -> Bool
thumbsUpPlanA (StrictArg {}) = Bool
False
thumbsUpPlanA (CastIt Coercion
_ SimplCont
k) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
thumbsUpPlanA (TickIt Tickish Id
_ SimplCont
k) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
thumbsUpPlanA (ApplyToVal { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
thumbsUpPlanA (ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
k }) = SimplCont -> Bool
thumbsUpPlanA SimplCont
k
thumbsUpPlanA (Select {}) = Bool
True
thumbsUpPlanA (StrictBind {}) = Bool
True
thumbsUpPlanA (Stop {}) = Bool
True
mkDupableContWithDmds SimplEnv
env [Demand]
dmds
(ApplyToTy { sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_arg_ty :: SimplCont -> Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty })
= do { (SimplFloats
floats, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
floats, ApplyToTy :: Kind -> Kind -> SimplCont -> SimplCont
ApplyToTy { sc_cont :: SimplCont
sc_cont = SimplCont
cont'
, sc_arg_ty :: Kind
sc_arg_ty = Kind
arg_ty, sc_hole_ty :: Kind
sc_hole_ty = Kind
hole_ty }) }
mkDupableContWithDmds SimplEnv
env [Demand]
dmds
(ApplyToVal { sc_arg :: SimplCont -> CoreExpr
sc_arg = CoreExpr
arg, sc_dup :: SimplCont -> DupFlag
sc_dup = DupFlag
dup, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se
, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont, sc_hole_ty :: SimplCont -> Kind
sc_hole_ty = Kind
hole_ty })
=
do { let (Demand
dmd:[Demand]
_) = [Demand]
dmds
; (SimplFloats
floats1, SimplCont
cont') <- SimplEnv
-> [Demand] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableContWithDmds SimplEnv
env [Demand]
dmds SimplCont
cont
; let env' :: SimplEnv
env' = SimplEnv
env SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats1
; (DupFlag
_, SimplEnv
se', CoreExpr
arg') <- SimplEnv
-> DupFlag
-> SimplEnv
-> CoreExpr
-> SimplM (DupFlag, SimplEnv, CoreExpr)
simplArg SimplEnv
env' DupFlag
dup SimplEnv
se CoreExpr
arg
; (LetFloats
let_floats2, CoreExpr
arg'') <- SimplMode
-> TopLevelFlag
-> Demand
-> FastString
-> CoreExpr
-> SimplM (LetFloats, CoreExpr)
makeTrivial (SimplEnv -> SimplMode
getMode SimplEnv
env) TopLevelFlag
NotTopLevel Demand
dmd ([Char] -> FastString
fsLit [Char]
"karg") CoreExpr
arg'
; let all_floats :: SimplFloats
all_floats = SimplFloats
floats1 SimplFloats -> LetFloats -> SimplFloats
`addLetFloats` LetFloats
let_floats2
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplFloats
all_floats
, ApplyToVal :: DupFlag -> Kind -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
ApplyToVal { sc_arg :: CoreExpr
sc_arg = CoreExpr
arg''
, sc_env :: SimplEnv
sc_env = SimplEnv
se' SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
all_floats
, sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup, sc_cont :: SimplCont
sc_cont = SimplCont
cont'
, sc_hole_ty :: Kind
sc_hole_ty = Kind
hole_ty }) }
mkDupableContWithDmds SimplEnv
env [Demand]
_
(Select { sc_bndr :: SimplCont -> Id
sc_bndr = Id
case_bndr, sc_alts :: SimplCont -> [Alt Id]
sc_alts = [Alt Id]
alts, sc_env :: SimplCont -> SimplEnv
sc_env = SimplEnv
se, sc_cont :: SimplCont -> SimplCont
sc_cont = SimplCont
cont })
=
do { Tick -> SimplM ()
tick (Id -> Tick
CaseOfCase Id
case_bndr)
; (SimplFloats
floats, SimplCont
alt_cont) <- SimplEnv
-> [Alt Id] -> SimplCont -> SimplM (SimplFloats, SimplCont)
mkDupableCaseCont SimplEnv
env [Alt Id]
alts SimplCont
cont
; let alt_env :: SimplEnv
alt_env = SimplEnv
se SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
floats
; let cont_scaling :: Kind
cont_scaling = SimplCont -> Kind
contHoleScaling SimplCont
cont
; (SimplEnv
alt_env', Id
case_bndr') <- SimplEnv -> Id -> SimplM (SimplEnv, Id)
simplBinder SimplEnv
alt_env (Kind -> Id -> Id
scaleIdBy Kind
cont_scaling Id
case_bndr)
; [Alt Id]
alts' <- (Alt Id -> SimplM (Alt Id)) -> [Alt Id] -> SimplM [Alt Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv
-> Maybe CoreExpr
-> [AltCon]
-> Id
-> SimplCont
-> Alt Id
-> SimplM (Alt Id)
simplAlt SimplEnv
alt_env' Maybe CoreExpr
forall a. Maybe a
Nothing [] Id
case_bndr' SimplCont
alt_cont) (Kind -> [Alt Id] -> [Alt Id]
scaleAltsBy Kind
cont_scaling [Alt Id]
alts)
; (JoinFloats
join_floats, [Alt Id]
alts'') <- (JoinFloats -> Alt Id -> SimplM (JoinFloats, Alt Id))
-> JoinFloats -> [Alt Id] -> SimplM (JoinFloats, [Alt Id])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM (Platform
-> Id -> JoinFloats -> Alt Id -> SimplM (JoinFloats, Alt Id)
mkDupableAlt (DynFlags -> Platform
targetPlatform (SimplEnv -> DynFlags
seDynFlags SimplEnv
env)) Id
case_bndr')
JoinFloats
emptyJoinFloats [Alt Id]
alts'
; let all_floats :: SimplFloats
all_floats = SimplFloats
floats SimplFloats -> JoinFloats -> SimplFloats
`addJoinFloats` JoinFloats
join_floats
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats
all_floats
, Select :: DupFlag -> Id -> [Alt Id] -> SimplEnv -> SimplCont -> SimplCont
Select { sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup
, sc_bndr :: Id
sc_bndr = Id
case_bndr'
, sc_alts :: [Alt Id]
sc_alts = [Alt Id]
alts''
, sc_env :: SimplEnv
sc_env = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
se SimplEnv -> SimplFloats -> SimplEnv
`setInScopeFromF` SimplFloats
all_floats
, sc_cont :: SimplCont
sc_cont = Kind -> SimplCont
mkBoringStop (SimplCont -> Kind
contResultType SimplCont
cont) } ) }
mkDupableStrictBind :: SimplEnv -> OutId -> OutExpr -> OutType
-> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind :: SimplEnv
-> Id -> CoreExpr -> Kind -> SimplM (SimplFloats, SimplCont)
mkDupableStrictBind SimplEnv
env Id
arg_bndr CoreExpr
join_rhs Kind
res_ty
| CoreExpr -> Bool
exprIsTrivial CoreExpr
join_rhs
= (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env
, StrictBind :: DupFlag
-> Id -> [Id] -> CoreExpr -> SimplEnv -> SimplCont -> SimplCont
StrictBind { sc_bndr :: Id
sc_bndr = Id
arg_bndr, sc_bndrs :: [Id]
sc_bndrs = []
, sc_body :: CoreExpr
sc_body = CoreExpr
join_rhs
, sc_env :: SimplEnv
sc_env = SimplEnv -> SimplEnv
zapSubstEnv SimplEnv
env
, sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup
, sc_cont :: SimplCont
sc_cont = Kind -> SimplCont
mkBoringStop Kind
res_ty } )
| Bool
otherwise
= do { Id
join_bndr <- [Id] -> Kind -> SimplM Id
newJoinId [Id
arg_bndr] Kind
res_ty
; let arg_info :: ArgInfo
arg_info = ArgInfo :: Id
-> [ArgSpec]
-> FunRules
-> Bool
-> [Demand]
-> [JoinArity]
-> ArgInfo
ArgInfo { ai_fun :: Id
ai_fun = Id
join_bndr
, ai_rules :: FunRules
ai_rules = FunRules
forall a. Maybe a
Nothing, ai_args :: [ArgSpec]
ai_args = []
, ai_encl :: Bool
ai_encl = Bool
False, ai_dmds :: [Demand]
ai_dmds = Demand -> [Demand]
forall a. a -> [a]
repeat Demand
topDmd
, ai_discs :: [JoinArity]
ai_discs = JoinArity -> [JoinArity]
forall a. a -> [a]
repeat JoinArity
0 }
; (SimplFloats, SimplCont) -> SimplM (SimplFloats, SimplCont)
forall (m :: * -> *) a. Monad m => a -> m a
return ( SimplFloats -> JoinFloats -> SimplFloats
addJoinFloats (SimplEnv -> SimplFloats
emptyFloats SimplEnv
env) (JoinFloats -> SimplFloats) -> JoinFloats -> SimplFloats
forall a b. (a -> b) -> a -> b
$
InBind -> JoinFloats
unitJoinFloat (InBind -> JoinFloats) -> InBind -> JoinFloats
forall a b. (a -> b) -> a -> b
$
Id -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec Id
join_bndr (CoreExpr -> InBind) -> CoreExpr -> InBind
forall a b. (a -> b) -> a -> b
$
Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam (Id -> Id
setOneShotLambda Id
arg_bndr) CoreExpr
join_rhs
, StrictArg :: DupFlag -> ArgInfo -> Kind -> SimplCont -> SimplCont
StrictArg { sc_dup :: DupFlag
sc_dup = DupFlag
OkToDup
, sc_fun :: ArgInfo
sc_fun = ArgInfo
arg_info
, sc_fun_ty :: Kind
sc_fun_ty = Id -> Kind
idType Id
join_bndr
, sc_cont :: SimplCont
sc_cont = Kind -> SimplCont
mkBoringStop Kind
res_ty
} ) }
mkDupableAlt :: Platform -> OutId
-> JoinFloats -> OutAlt
-> SimplM (JoinFloats, OutAlt)
mkDupableAlt :: Platform
-> Id -> JoinFloats -> Alt Id -> SimplM (JoinFloats, Alt Id)
mkDupableAlt Platform
_platform Id
case_bndr JoinFloats
jfloats (AltCon
con, [Id]
bndrs', CoreExpr
rhs')
| CoreExpr -> Bool
exprIsTrivial CoreExpr
rhs'
= (JoinFloats, Alt Id) -> SimplM (JoinFloats, Alt Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (JoinFloats
jfloats, (AltCon
con, [Id]
bndrs', CoreExpr
rhs'))
| Bool
otherwise
= do { let rhs_ty' :: Kind
rhs_ty' = CoreExpr -> Kind
exprType CoreExpr
rhs'
scrut_ty :: Kind
scrut_ty = Id -> Kind
idType Id
case_bndr
case_bndr_w_unf :: Id
case_bndr_w_unf
= case AltCon
con of
AltCon
DEFAULT -> Id
case_bndr
DataAlt DataCon
dc -> Id -> Unfolding -> Id
setIdUnfolding Id
case_bndr Unfolding
unf
where
unf :: Unfolding
unf = CoreExpr -> Unfolding
mkInlineUnfolding CoreExpr
forall {b}. Expr b
rhs
rhs :: Expr b
rhs = DataCon -> [Kind] -> [Id] -> Expr b
forall b. DataCon -> [Kind] -> [Id] -> Expr b
mkConApp2 DataCon
dc (Kind -> [Kind]
tyConAppArgs Kind
scrut_ty) [Id]
bndrs'
LitAlt {} -> WARN( True, text "mkDupableAlt"
<+> ppr case_bndr <+> ppr con )
Id
case_bndr
final_bndrs' :: [Id]
final_bndrs'
| Id -> Bool
isDeadBinder Id
case_bndr = (Id -> Bool) -> [Id] -> [Id]
forall a. (a -> Bool) -> [a] -> [a]
filter Id -> Bool
abstract_over [Id]
bndrs'
| Bool
otherwise = [Id]
bndrs' [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ [Id
case_bndr_w_unf]
abstract_over :: Id -> Bool
abstract_over Id
bndr
| Id -> Bool
isTyVar Id
bndr = Bool
True
| Bool
otherwise = Bool -> Bool
not (Id -> Bool
isDeadBinder Id
bndr)
final_args :: [Expr b]
final_args = [Id] -> [Expr b]
forall b. [Id] -> [Expr b]
varsToCoreExprs [Id]
final_bndrs'
really_final_bndrs :: [Id]
really_final_bndrs = (Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Id
one_shot [Id]
final_bndrs'
one_shot :: Id -> Id
one_shot Id
v | Id -> Bool
isId Id
v = Id -> Id
setOneShotLambda Id
v
| Bool
otherwise = Id
v
join_rhs :: CoreExpr
join_rhs = [Id] -> CoreExpr -> CoreExpr
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
really_final_bndrs CoreExpr
rhs'
; Id
join_bndr <- [Id] -> Kind -> SimplM Id
newJoinId [Id]
final_bndrs' Kind
rhs_ty'
; let join_call :: Expr b
join_call = Expr b -> [Expr b] -> Expr b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Expr b
forall b. Id -> Expr b
Var Id
join_bndr) [Expr b]
forall {b}. [Expr b]
final_args
alt' :: (AltCon, [Id], Expr b)
alt' = (AltCon
con, [Id]
bndrs', Expr b
forall {b}. Expr b
join_call)
; (JoinFloats, Alt Id) -> SimplM (JoinFloats, Alt Id)
forall (m :: * -> *) a. Monad m => a -> m a
return ( JoinFloats
jfloats JoinFloats -> JoinFloats -> JoinFloats
`addJoinFlts` InBind -> JoinFloats
unitJoinFloat (Id -> CoreExpr -> InBind
forall b. b -> Expr b -> Bind b
NonRec Id
join_bndr CoreExpr
join_rhs)
, Alt Id
forall {b}. (AltCon, [Id], Expr b)
alt') }
simplLetUnfolding :: SimplEnv-> TopLevelFlag
-> MaybeJoinCont
-> InId
-> OutExpr -> OutType -> ArityType
-> Unfolding -> SimplM Unfolding
simplLetUnfolding :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> CoreExpr
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplLetUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
cont_mb Id
id CoreExpr
new_rhs Kind
rhs_ty ArityType
arity Unfolding
unf
| Unfolding -> Bool
isStableUnfolding Unfolding
unf
= SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
cont_mb Id
id Kind
rhs_ty ArityType
arity Unfolding
unf
| Id -> Bool
isExitJoinId Id
id
= Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
noUnfolding
| Bool
otherwise
= DynFlags
-> TopLevelFlag
-> UnfoldingSource
-> Id
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding (SimplEnv -> DynFlags
seDynFlags SimplEnv
env) TopLevelFlag
top_lvl UnfoldingSource
InlineRhs Id
id CoreExpr
new_rhs
mkLetUnfolding :: DynFlags -> TopLevelFlag -> UnfoldingSource
-> InId -> OutExpr -> SimplM Unfolding
mkLetUnfolding :: DynFlags
-> TopLevelFlag
-> UnfoldingSource
-> Id
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding !DynFlags
dflags TopLevelFlag
top_lvl UnfoldingSource
src Id
id CoreExpr
new_rhs
= Bool
is_bottoming Bool -> SimplM Unfolding -> SimplM Unfolding
`seq`
Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return (DynFlags
-> UnfoldingSource -> Bool -> Bool -> CoreExpr -> Unfolding
mkUnfolding DynFlags
dflags UnfoldingSource
src Bool
is_top_lvl Bool
is_bottoming CoreExpr
new_rhs)
where
!is_top_lvl :: Bool
is_top_lvl = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
!is_bottoming :: Bool
is_bottoming = Id -> Bool
isDeadEndId Id
id
simplStableUnfolding :: SimplEnv -> TopLevelFlag
-> MaybeJoinCont
-> InId
-> OutType
-> ArityType
-> Unfolding
->SimplM Unfolding
simplStableUnfolding :: SimplEnv
-> TopLevelFlag
-> MaybeJoinCont
-> Id
-> Kind
-> ArityType
-> Unfolding
-> SimplM Unfolding
simplStableUnfolding SimplEnv
env TopLevelFlag
top_lvl MaybeJoinCont
mb_cont Id
id Kind
rhs_ty ArityType
id_arity Unfolding
unf
= case Unfolding
unf of
Unfolding
NoUnfolding -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
Unfolding
BootUnfolding -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
OtherCon {} -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
unf
DFunUnfolding { df_bndrs :: Unfolding -> [Id]
df_bndrs = [Id]
bndrs, df_con :: Unfolding -> DataCon
df_con = DataCon
con, df_args :: Unfolding -> [CoreExpr]
df_args = [CoreExpr]
args }
-> do { (SimplEnv
env', [Id]
bndrs') <- SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplBinders SimplEnv
unf_env [Id]
bndrs
; [CoreExpr]
args' <- (CoreExpr -> SimplM CoreExpr) -> [CoreExpr] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env') [CoreExpr]
args
; Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id] -> DataCon -> [CoreExpr] -> Unfolding
mkDFunUnfolding [Id]
bndrs' DataCon
con [CoreExpr]
args') }
CoreUnfolding { uf_tmpl :: Unfolding -> CoreExpr
uf_tmpl = CoreExpr
expr, uf_src :: Unfolding -> UnfoldingSource
uf_src = UnfoldingSource
src, uf_guidance :: Unfolding -> UnfoldingGuidance
uf_guidance = UnfoldingGuidance
guide }
| UnfoldingSource -> Bool
isStableSource UnfoldingSource
src
-> do { CoreExpr
expr' <- case MaybeJoinCont
mb_cont of
Just SimplCont
cont ->
SimplEnv -> Id -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplJoinRhs SimplEnv
unf_env Id
id CoreExpr
expr SimplCont
cont
MaybeJoinCont
Nothing ->
do { CoreExpr
expr' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
unf_env CoreExpr
expr (Kind -> SimplCont
mkBoringStop Kind
rhs_ty)
; CoreExpr -> SimplM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr -> CoreExpr
eta_expand CoreExpr
expr') }
; case UnfoldingGuidance
guide of
UnfWhen { ug_arity :: UnfoldingGuidance -> JoinArity
ug_arity = JoinArity
arity
, ug_unsat_ok :: UnfoldingGuidance -> Bool
ug_unsat_ok = Bool
sat_ok
, ug_boring_ok :: UnfoldingGuidance -> Bool
ug_boring_ok = Bool
boring_ok
}
-> let !new_boring_ok :: Bool
new_boring_ok = Bool
boring_ok Bool -> Bool -> Bool
|| CoreExpr -> Bool
inlineBoringOk CoreExpr
expr'
guide' :: UnfoldingGuidance
guide' =
UnfWhen :: JoinArity -> Bool -> Bool -> UnfoldingGuidance
UnfWhen { ug_arity :: JoinArity
ug_arity = JoinArity
arity
, ug_unsat_ok :: Bool
ug_unsat_ok = Bool
sat_ok
, ug_boring_ok :: Bool
ug_boring_ok = Bool
new_boring_ok
}
in Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return (UnfoldingSource
-> Bool -> CoreExpr -> UnfoldingGuidance -> Unfolding
mkCoreUnfolding UnfoldingSource
src Bool
is_top_lvl CoreExpr
expr' UnfoldingGuidance
guide')
UnfoldingGuidance
_other
-> DynFlags
-> TopLevelFlag
-> UnfoldingSource
-> Id
-> CoreExpr
-> SimplM Unfolding
mkLetUnfolding DynFlags
dflags TopLevelFlag
top_lvl UnfoldingSource
src Id
id CoreExpr
expr' }
| Bool
otherwise -> Unfolding -> SimplM Unfolding
forall (m :: * -> *) a. Monad m => a -> m a
return Unfolding
noUnfolding
where
dflags :: DynFlags
dflags = SimplEnv -> DynFlags
seDynFlags SimplEnv
env
!is_top_lvl :: Bool
is_top_lvl = TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl
act :: Activation
act = Id -> Activation
idInlineActivation Id
id
unf_env :: SimplEnv
unf_env = (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode (Activation -> SimplMode -> SimplMode
updModeForStableUnfoldings Activation
act) SimplEnv
env
eta_expand :: CoreExpr -> CoreExpr
eta_expand CoreExpr
expr
| Bool -> Bool
not Bool
eta_on = CoreExpr
expr
| CoreExpr -> Bool
exprIsTrivial CoreExpr
expr = CoreExpr
expr
| Bool
otherwise = ArityType -> CoreExpr -> CoreExpr
etaExpandAT ArityType
id_arity CoreExpr
expr
eta_on :: Bool
eta_on = SimplMode -> Bool
sm_eta_expand (SimplEnv -> SimplMode
getMode SimplEnv
env)
addBndrRules :: SimplEnv -> InBndr -> OutBndr
-> MaybeJoinCont
-> SimplM (SimplEnv, OutBndr)
addBndrRules :: SimplEnv -> Id -> Id -> MaybeJoinCont -> SimplM (SimplEnv, Id)
addBndrRules SimplEnv
env Id
in_id Id
out_id MaybeJoinCont
mb_cont
| [CoreRule] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CoreRule]
old_rules
= (SimplEnv, Id) -> SimplM (SimplEnv, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv
env, Id
out_id)
| Bool
otherwise
= do { [CoreRule]
new_rules <- SimplEnv
-> Maybe Id -> [CoreRule] -> MaybeJoinCont -> SimplM [CoreRule]
simplRules SimplEnv
env (Id -> Maybe Id
forall a. a -> Maybe a
Just Id
out_id) [CoreRule]
old_rules MaybeJoinCont
mb_cont
; let final_id :: Id
final_id = Id
out_id Id -> RuleInfo -> Id
`setIdSpecialisation` [CoreRule] -> RuleInfo
mkRuleInfo [CoreRule]
new_rules
; (SimplEnv, Id) -> SimplM (SimplEnv, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplEnv -> Id -> SimplEnv
modifyInScope SimplEnv
env Id
final_id, Id
final_id) }
where
old_rules :: [CoreRule]
old_rules = RuleInfo -> [CoreRule]
ruleInfoRules (Id -> RuleInfo
idSpecialisation Id
in_id)
simplRules :: SimplEnv -> Maybe OutId -> [CoreRule]
-> MaybeJoinCont -> SimplM [CoreRule]
simplRules :: SimplEnv
-> Maybe Id -> [CoreRule] -> MaybeJoinCont -> SimplM [CoreRule]
simplRules SimplEnv
env Maybe Id
mb_new_id [CoreRule]
rules MaybeJoinCont
mb_cont
= (CoreRule -> SimplM CoreRule) -> [CoreRule] -> SimplM [CoreRule]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM CoreRule -> SimplM CoreRule
simpl_rule [CoreRule]
rules
where
simpl_rule :: CoreRule -> SimplM CoreRule
simpl_rule rule :: CoreRule
rule@(BuiltinRule {})
= CoreRule -> SimplM CoreRule
forall (m :: * -> *) a. Monad m => a -> m a
return CoreRule
rule
simpl_rule rule :: CoreRule
rule@(Rule { ru_bndrs :: CoreRule -> [Id]
ru_bndrs = [Id]
bndrs, ru_args :: CoreRule -> [CoreExpr]
ru_args = [CoreExpr]
args
, ru_fn :: CoreRule -> Name
ru_fn = Name
fn_name, ru_rhs :: CoreRule -> CoreExpr
ru_rhs = CoreExpr
rhs })
= do { (SimplEnv
env', [Id]
bndrs') <- SimplEnv -> [Id] -> SimplM (SimplEnv, [Id])
simplBinders SimplEnv
env [Id]
bndrs
; let rhs_ty :: Kind
rhs_ty = SimplEnv -> Kind -> Kind
substTy SimplEnv
env' (CoreExpr -> Kind
exprType CoreExpr
rhs)
rhs_cont :: SimplCont
rhs_cont = case MaybeJoinCont
mb_cont of
MaybeJoinCont
Nothing -> Kind -> SimplCont
mkBoringStop Kind
rhs_ty
Just SimplCont
cont -> ASSERT2( join_ok, bad_join_msg )
SimplCont
cont
rule_env :: SimplEnv
rule_env = (SimplMode -> SimplMode) -> SimplEnv -> SimplEnv
updMode SimplMode -> SimplMode
updModeForRules SimplEnv
env'
fn_name' :: Name
fn_name' = case Maybe Id
mb_new_id of
Just Id
id -> Id -> Name
idName Id
id
Maybe Id
Nothing -> Name
fn_name
join_ok :: Bool
join_ok = case Maybe Id
mb_new_id of
Just Id
id | Just JoinArity
join_arity <- Id -> Maybe JoinArity
isJoinId_maybe Id
id
-> [CoreExpr] -> JoinArity
forall (t :: * -> *) a. Foldable t => t a -> JoinArity
length [CoreExpr]
args JoinArity -> JoinArity -> Bool
forall a. Eq a => a -> a -> Bool
== JoinArity
join_arity
Maybe Id
_ -> Bool
False
bad_join_msg :: SDoc
bad_join_msg = [SDoc] -> SDoc
vcat [ Maybe Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe Id
mb_new_id, CoreRule -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreRule
rule
, Maybe (Maybe JoinArity) -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((Id -> Maybe JoinArity) -> Maybe Id -> Maybe (Maybe JoinArity)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Id -> Maybe JoinArity
isJoinId_maybe Maybe Id
mb_new_id) ]
; [CoreExpr]
args' <- (CoreExpr -> SimplM CoreExpr) -> [CoreExpr] -> SimplM [CoreExpr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
rule_env) [CoreExpr]
args
; CoreExpr
rhs' <- SimplEnv -> CoreExpr -> SimplCont -> SimplM CoreExpr
simplExprC SimplEnv
rule_env CoreExpr
rhs SimplCont
rhs_cont
; CoreRule -> SimplM CoreRule
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreRule
rule { ru_bndrs :: [Id]
ru_bndrs = [Id]
bndrs'
, ru_fn :: Name
ru_fn = Name
fn_name'
, ru_args :: [CoreExpr]
ru_args = [CoreExpr]
args'
, ru_rhs :: CoreExpr
ru_rhs = CoreExpr
rhs' }) }